inweb-bootstrap/docs/inweb/3-ta.html
2020-04-21 17:55:17 +01:00

472 lines
109 KiB
HTML

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>The Analyser</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/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>
<nav role="navigation">
<h1><a href="../index.html">
<img src="../docs-assets/Octagram.png" width=72 height=72">
</a></h1>
<ul><li><a href="index.html"><span class="selectedlink">inweb</span></a></li>
</ul><h2>Foundation Module</h2><ul>
<li><a href="../foundation-module/index.html">foundation</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 'The Analyser' generated by Inweb-->
<ul class="crumbs"><li><a href="../index.html">Home</a></li><li><a href="index.html">inweb</a></li><li><a href="index.html#3">Chapter 3: Outputs</a></li><li><b>The Analyser</b></li></ul><p class="purpose">Here we analyse the code in the web, enabling us to see how functions and data structures are used within the program.</p>
<ul class="toc"><li><a href="3-ta.html#SP1">&#167;1. Scanning webs</a></li><li><a href="3-ta.html#SP2">&#167;2. The section catalogue</a></li><li><a href="3-ta.html#SP3">&#167;3. Analysing code</a></li><li><a href="3-ta.html#SP5">&#167;5. Identifier searching</a></li><li><a href="3-ta.html#SP6">&#167;6. The identifier hash table</a></li><li><a href="3-ta.html#SP13">&#167;13. Open-source project support</a></li></ul><hr class="tocbar">
<p class="inwebparagraph"><a id="SP1"></a><b>&#167;1. Scanning webs. </b>This scanner is intended for debugging Inweb, and simply shows the main
result of reading in and parsing the web:
</p>
<pre class="displayed-code all-displayed-code">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Analyser::scan_line_categories</span><button class="popup" onclick="togglePopup('usagePopup1')">...<span class="popuptext" id="usagePopup1">Usage of <b>Analyser::scan_line_categories</b>:<br>Program Control - <a href="1-pc.html#SP7_4_1">&#167;7.4.1</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">web</span><span class="plain-syntax"> *</span><span class="identifier-syntax">W</span><span class="plain-syntax">, </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">range</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">PRINT</span><span class="plain-syntax">(</span><span class="string-syntax">"Scan of source lines for '%S'\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">range</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">count</span><span class="plain-syntax"> = </span><span class="constant-syntax">1</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">chapter</span><span class="plain-syntax"> *</span><span class="identifier-syntax">C</span><span class="plain-syntax"> = </span><a href="2-tr.html#SP8" class="internal">Reader::get_chapter_for_range</a><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">, </span><span class="identifier-syntax">range</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">C</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">section</span><span class="plain-syntax"> *</span><span class="identifier-syntax">S</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">S</span><span class="plain-syntax">, </span><span class="reserved-syntax">section</span><span class="plain-syntax">, </span><span class="identifier-syntax">C</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">sections</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">source_line</span><span class="plain-syntax"> *</span><span class="identifier-syntax">L</span><span class="plain-syntax"> = </span><span class="identifier-syntax">S</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">first_line</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"> = </span><span class="identifier-syntax">L</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_line</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span>&lt;<span class="named-paragraph">Trace the content and category of this source line</span> <span class="named-paragraph-number">1.1</span>&gt;<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">section</span><span class="plain-syntax"> *</span><span class="identifier-syntax">S</span><span class="plain-syntax"> = </span><a href="2-tr.html#SP8" class="internal">Reader::get_section_for_range</a><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">, </span><span class="identifier-syntax">range</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">S</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">source_line</span><span class="plain-syntax"> *</span><span class="identifier-syntax">L</span><span class="plain-syntax"> = </span><span class="identifier-syntax">S</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">first_line</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"> = </span><span class="identifier-syntax">L</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_line</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span>&lt;<span class="named-paragraph">Trace the content and category of this source line</span> <span class="named-paragraph-number">1.1</span>&gt;
<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">LOOP_OVER_LINKED_LIST</span><span class="plain-syntax">(</span><span class="identifier-syntax">C</span><span class="plain-syntax">, </span><span class="reserved-syntax">chapter</span><span class="plain-syntax">, </span><span class="identifier-syntax">W</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">chapters</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">S</span><span class="plain-syntax">, </span><span class="reserved-syntax">section</span><span class="plain-syntax">, </span><span class="identifier-syntax">C</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">sections</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">source_line</span><span class="plain-syntax"> *</span><span class="identifier-syntax">L</span><span class="plain-syntax"> = </span><span class="identifier-syntax">S</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">first_line</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"> = </span><span class="identifier-syntax">L</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_line</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span>&lt;<span class="named-paragraph">Trace the content and category of this source line</span> <span class="named-paragraph-number">1.1</span>&gt;<span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax">}</span>
</pre><p class="inwebparagraph"><a id="SP1_1"></a><b>&#167;1.1. </b><code class="display">
&lt;<span class="named-paragraph-defn">Trace the content and category of this source line</span> <span class="named-paragraph-number">1.1</span>&gt; =
</code></p>
<pre class="displayed-code all-displayed-code">
<span class="plain-syntax"> </span><span class="identifier-syntax">TEMPORARY_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">C</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">C</span><span class="plain-syntax">, </span><span class="string-syntax">"%s"</span><span class="plain-syntax">, </span><a href="2-lc.html#SP4" class="internal">Lines::category_name</a><span class="plain-syntax">(</span><span class="identifier-syntax">L</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">category</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">while</span><span class="plain-syntax"> (</span><a href="../foundation-module/4-sm.html#SP8" class="internal">Str::len</a><span class="plain-syntax">(</span><span class="identifier-syntax">C</span><span class="plain-syntax">) &lt; </span><span class="constant-syntax">20</span><span class="plain-syntax">) </span><span class="identifier-syntax">PUT_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">C</span><span class="plain-syntax">, </span><span class="character-syntax">'.'</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">PRINT</span><span class="plain-syntax">(</span><span class="string-syntax">"%07d %S %S\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">count</span><span class="plain-syntax">++, </span><span class="identifier-syntax">C</span><span class="plain-syntax">, </span><span class="identifier-syntax">L</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">text</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">C</span><span class="plain-syntax">);</span>
</pre><ul class="endnotetexts"><li>This code is used in <a href="3-ta.html#SP1">&#167;1</a> (three times).</li></ul><p class="inwebparagraph"><a id="SP2"></a><b>&#167;2. The section catalogue. </b>This provides quite a useful overview of the sections. As we'll see frequently
in Chapter 4, we call out to a general routine in Chapter 5 to provide
annotations which are programming-language specific; the aim is to abstract
so that Chapter 4 contains no assumptions about the language.
</p>
<pre class="definitions">
<span class="definition-keyword">enum</span> <span class="constant-syntax">BASIC_SECTIONCAT</span><span class="plain-syntax"> </span><span class="identifier-syntax">from</span><span class="plain-syntax"> </span><span class="constant-syntax">1</span>
<span class="definition-keyword">enum</span> <span class="constant-syntax">STRUCTURES_SECTIONCAT</span>
<span class="definition-keyword">enum</span> <span class="constant-syntax">FUNCTIONS_SECTIONCAT</span>
</pre>
<pre class="displayed-code all-displayed-code">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Analyser::catalogue_the_sections</span><button class="popup" onclick="togglePopup('usagePopup2')">...<span class="popuptext" id="usagePopup2">Usage of <b>Analyser::catalogue_the_sections</b>:<br>Program Control - <a href="1-pc.html#SP7_4_1">&#167;7.4.1</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">web</span><span class="plain-syntax"> *</span><span class="identifier-syntax">W</span><span class="plain-syntax">, </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">range</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">form</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">max_width</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">, </span><span class="identifier-syntax">max_range_width</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">chapter</span><span class="plain-syntax"> *</span><span class="identifier-syntax">C</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">section</span><span class="plain-syntax"> *</span><span class="identifier-syntax">S</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">C</span><span class="plain-syntax">, </span><span class="reserved-syntax">chapter</span><span class="plain-syntax">, </span><span class="identifier-syntax">W</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">chapters</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">S</span><span class="plain-syntax">, </span><span class="reserved-syntax">section</span><span class="plain-syntax">, </span><span class="identifier-syntax">C</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">sections</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">max_range_width</span><span class="plain-syntax"> &lt; </span><a href="../foundation-module/4-sm.html#SP8" class="internal">Str::len</a><span class="plain-syntax">(</span><span class="identifier-syntax">S</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">md</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">sect_range</span><span class="plain-syntax">)) </span><span class="identifier-syntax">max_range_width</span><span class="plain-syntax"> = </span><a href="../foundation-module/4-sm.html#SP8" class="internal">Str::len</a><span class="plain-syntax">(</span><span class="identifier-syntax">S</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">md</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">sect_range</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">TEMPORARY_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">main_title</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">main_title</span><span class="plain-syntax">, </span><span class="string-syntax">"%S/%S"</span><span class="plain-syntax">, </span><span class="identifier-syntax">C</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">md</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">ch_basic_title</span><span class="plain-syntax">, </span><span class="identifier-syntax">S</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">md</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">sect_title</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">max_width</span><span class="plain-syntax"> &lt; </span><a href="../foundation-module/4-sm.html#SP8" class="internal">Str::len</a><span class="plain-syntax">(</span><span class="identifier-syntax">main_title</span><span class="plain-syntax">)) </span><span class="identifier-syntax">max_width</span><span class="plain-syntax"> = </span><a href="../foundation-module/4-sm.html#SP8" class="internal">Str::len</a><span class="plain-syntax">(</span><span class="identifier-syntax">main_title</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">main_title</span><span class="plain-syntax">);</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">C</span><span class="plain-syntax">, </span><span class="reserved-syntax">chapter</span><span class="plain-syntax">, </span><span class="identifier-syntax">W</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">chapters</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><a href="../foundation-module/4-sm.html#SP22" class="internal">Str::eq_wide_string</a><span class="plain-syntax">(</span><span class="identifier-syntax">range</span><span class="plain-syntax">, </span><span class="identifier-syntax">L</span><span class="string-syntax">"0"</span><span class="plain-syntax">)) || (</span><a href="../foundation-module/4-sm.html#SP19" class="internal">Str::eq</a><span class="plain-syntax">(</span><span class="identifier-syntax">range</span><span class="plain-syntax">, </span><span class="identifier-syntax">C</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">md</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">ch_range</span><span class="plain-syntax">))) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">PRINT</span><span class="plain-syntax">(</span><span class="string-syntax">" -----\n"</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">S</span><span class="plain-syntax">, </span><span class="reserved-syntax">section</span><span class="plain-syntax">, </span><span class="identifier-syntax">C</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">sections</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">TEMPORARY_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">main_title</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">main_title</span><span class="plain-syntax">, </span><span class="string-syntax">"%S/%S"</span><span class="plain-syntax">, </span><span class="identifier-syntax">C</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">md</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">ch_basic_title</span><span class="plain-syntax">, </span><span class="identifier-syntax">S</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">md</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">sect_title</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">PRINT</span><span class="plain-syntax">(</span><span class="string-syntax">"%4d %S"</span><span class="plain-syntax">, </span><span class="identifier-syntax">S</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">sect_extent</span><span class="plain-syntax">, </span><span class="identifier-syntax">S</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">md</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">sect_range</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">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax"> = </span><a href="../foundation-module/4-sm.html#SP8" class="internal">Str::len</a><span class="plain-syntax">(</span><span class="identifier-syntax">S</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">md</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">sect_range</span><span class="plain-syntax">); </span><span class="identifier-syntax">i</span><span class="plain-syntax">&lt;</span><span class="identifier-syntax">max_range_width</span><span class="plain-syntax">+2; </span><span class="identifier-syntax">i</span><span class="plain-syntax">++) </span><span class="identifier-syntax">PRINT</span><span class="plain-syntax">(</span><span class="string-syntax">" "</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">PRINT</span><span class="plain-syntax">(</span><span class="string-syntax">"%S"</span><span class="plain-syntax">, </span><span class="identifier-syntax">main_title</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">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax"> = </span><a href="../foundation-module/4-sm.html#SP8" class="internal">Str::len</a><span class="plain-syntax">(</span><span class="identifier-syntax">main_title</span><span class="plain-syntax">); </span><span class="identifier-syntax">i</span><span class="plain-syntax">&lt;</span><span class="identifier-syntax">max_width</span><span class="plain-syntax">+2; </span><span class="identifier-syntax">i</span><span class="plain-syntax">++) </span><span class="identifier-syntax">PRINT</span><span class="plain-syntax">(</span><span class="string-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">form</span><span class="plain-syntax"> != </span><span class="constant-syntax">BASIC_SECTIONCAT</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><a href="4-taf.html#SP8" class="internal">Functions::catalogue</a><span class="plain-syntax">(</span><span class="identifier-syntax">S</span><span class="plain-syntax">, (</span><span class="identifier-syntax">form</span><span class="plain-syntax"> == </span><span class="constant-syntax">FUNCTIONS_SECTIONCAT</span><span class="plain-syntax">)?</span><span class="identifier-syntax">TRUE:FALSE</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">PRINT</span><span class="plain-syntax">(</span><span class="string-syntax">"\n"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">main_title</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax">}</span>
</pre><p class="inwebparagraph"><a id="SP3"></a><b>&#167;3. Analysing code. </b>We can't pretend to a full-scale static analysis of the code &mdash; for one thing,
that would mean knowing more about the syntax of the web's language than we
actually do. So the following provides only a toolkit which other code can
use when looking for certain syntactic patterns: something which looks like
a function call, or a C structure field reference, for example. These are
all essentially based on spotting identifiers in the code, but with
punctuation around them.
</p>
<p class="inwebparagraph">Usage codes are used to define a set of allowed contexts in which to spot
these identifiers.
</p>
<pre class="definitions">
<span class="definition-keyword">define</span> <span class="constant-syntax">ELEMENT_ACCESS_USAGE</span><span class="plain-syntax"> </span><span class="constant-syntax">0x00000001</span><span class="plain-syntax"> </span><span class="comment"> C-like languages: access via </span><code class="display"><span class="extract-syntax">-&gt;</span></code><span class="comment"> or </span><code class="display"><span class="extract-syntax">.</span></code><span class="comment"> operators to structure element</span>
<span class="definition-keyword">define</span> <span class="constant-syntax">FCALL_USAGE</span><span class="plain-syntax"> </span><span class="constant-syntax">0x00000002</span><span class="plain-syntax"> </span><span class="comment"> C-like languages: function call made using brackets, </span><code class="display"><span class="extract-syntax">name(args)</span></code>
<span class="definition-keyword">define</span> <span class="constant-syntax">PREFORM_IN_CODE_USAGE</span><span class="plain-syntax"> </span><span class="constant-syntax">0x00000004</span><span class="plain-syntax"> </span><span class="comment"> InC only: use of a Preform nonterminal as a C "constant"</span>
<span class="definition-keyword">define</span> <span class="constant-syntax">PREFORM_IN_GRAMMAR_USAGE</span><span class="plain-syntax"> </span><span class="constant-syntax">0x00000008</span><span class="plain-syntax"> </span><span class="comment"> InC only: ditto, but within Preform production rather than C code</span>
<span class="definition-keyword">define</span> <span class="constant-syntax">MISC_USAGE</span><span class="plain-syntax"> </span><span class="constant-syntax">0x00000010</span><span class="plain-syntax"> </span><span class="comment"> any other appearance as an identifier</span>
<span class="definition-keyword">define</span> <span class="constant-syntax">ANY_USAGE</span><span class="plain-syntax"> </span><span class="constant-syntax">0x7fffffff</span><span class="plain-syntax"> </span><span class="comment"> any of the above</span>
</pre>
<p class="inwebparagraph"><a id="SP4"></a><b>&#167;4. </b>The main analysis routine goes through a web as follows. Note that we only
perform the search here, we don't comment on the results; any action to be
taken must be handled by <code class="display"><span class="extract-syntax">LanguageMethods::late_preweave_analysis</span></code> when we're done.
</p>
<pre class="displayed-code all-displayed-code">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Analyser::analyse_code</span><button class="popup" onclick="togglePopup('usagePopup3')">...<span class="popuptext" id="usagePopup3">Usage of <b>Analyser::analyse_code</b>:<br>The Swarm - <a href="1-ts.html#SP2">&#167;2</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">web</span><span class="plain-syntax"> *</span><span class="identifier-syntax">W</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">W</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">analysed</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span>&lt;<span class="named-paragraph">Ask language-specific code to identify search targets, and parse the Interfaces</span> <span class="named-paragraph-number">4.1</span>&gt;<span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">chapter</span><span class="plain-syntax"> *</span><span class="identifier-syntax">C</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">section</span><span class="plain-syntax"> *</span><span class="identifier-syntax">S</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_WITHIN_TANGLE</span><span class="plain-syntax">(</span><span class="identifier-syntax">C</span><span class="plain-syntax">, </span><span class="identifier-syntax">S</span><span class="plain-syntax">, </span><a href="3-tt.html#SP4" class="internal">Tangler::primary_target</a><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">switch</span><span class="plain-syntax"> (</span><span class="identifier-syntax">L</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">category</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">BEGIN_DEFINITION_LCAT:</span>
<span class="plain-syntax"> </span>&lt;<span class="named-paragraph">Perform analysis on the body of the definition</span> <span class="named-paragraph-number">4.3</span>&gt;<span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">CODE_BODY_LCAT:</span>
<span class="plain-syntax"> </span>&lt;<span class="named-paragraph">Perform analysis on a typical line of code</span> <span class="named-paragraph-number">4.2</span>&gt;<span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="identifier-syntax">PREFORM_GRAMMAR_LCAT:</span>
<span class="plain-syntax"> </span>&lt;<span class="named-paragraph">Perform analysis on productions in a Preform grammar</span> <span class="named-paragraph-number">4.4</span>&gt;<span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><a href="4-lm.html#SP28" class="internal">LanguageMethods::late_preweave_analysis</a><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">main_language</span><span class="plain-syntax">, </span><span class="identifier-syntax">W</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">W</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">analysed</span><span class="plain-syntax"> = </span><span class="constant-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre><p class="inwebparagraph"><a id="SP4_1"></a><b>&#167;4.1. </b>First, we call any language-specific code, whose task is to identify what we
should be looking for: for example, the C-like languages code tells us (see
below) to look for names of particular functions it knows about.
</p>
<p class="inwebparagraph">In Version 1 webs, this code is also expected to parse any Interface lines in
a section which it recognises, marking those by setting their
<code class="display"><span class="extract-syntax">interface_line_identified</span></code> flags. Any that are left must be erroneous.
Version 2 removed Interface altogeter as being cumbersome for no real gain in
practice.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="named-paragraph-defn">Ask language-specific code to identify search targets, and parse the Interfaces</span> <span class="named-paragraph-number">4.1</span>&gt; =
</code></p>
<pre class="displayed-code all-displayed-code">
<span class="plain-syntax"> </span><a href="4-lm.html#SP28" class="internal">LanguageMethods::early_preweave_analysis</a><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">main_language</span><span class="plain-syntax">, </span><span class="identifier-syntax">W</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">chapter</span><span class="plain-syntax"> *</span><span class="identifier-syntax">C</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">section</span><span class="plain-syntax"> *</span><span class="identifier-syntax">S</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_WITHIN_TANGLE</span><span class="plain-syntax">(</span><span class="identifier-syntax">C</span><span class="plain-syntax">, </span><span class="identifier-syntax">S</span><span class="plain-syntax">, </span><a href="3-tt.html#SP4" class="internal">Tangler::primary_target</a><span class="plain-syntax">(</span><span class="identifier-syntax">W</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">category</span><span class="plain-syntax"> == </span><span class="constant-syntax">INTERFACE_BODY_LCAT</span><span class="plain-syntax">) &amp;&amp;</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">L</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">interface_line_identified</span><span class="plain-syntax"> == </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">) &amp;&amp;</span>
<span class="plain-syntax"> (</span><a href="../foundation-module/4-pm.html#SP5" class="internal">Regexp::string_is_white_space</a><span class="plain-syntax">(</span><span class="identifier-syntax">L</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">text</span><span class="plain-syntax">) == </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><a href="1-pc.html#SP8" class="internal">Main::error_in_web</a><span class="plain-syntax">(</span><span class="identifier-syntax">I</span><span class="string-syntax">"unrecognised interface line"</span><span class="plain-syntax">, </span><span class="identifier-syntax">L</span><span class="plain-syntax">);</span>
</pre><ul class="endnotetexts"><li>This code is used in <a href="3-ta.html#SP4">&#167;4</a>.</li></ul><p class="inwebparagraph"><a id="SP4_2"></a><b>&#167;4.2. </b><code class="display">
&lt;<span class="named-paragraph-defn">Perform analysis on a typical line of code</span> <span class="named-paragraph-number">4.2</span>&gt; =
</code></p>
<pre class="displayed-code all-displayed-code">
<span class="plain-syntax"> </span><a href="3-ta.html#SP5" class="internal">Analyser::analyse_as_code</a><span class="plain-syntax">(</span><span class="identifier-syntax">W</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">text</span><span class="plain-syntax">, </span><span class="constant-syntax">ANY_USAGE</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">);</span>
</pre><ul class="endnotetexts"><li>This code is used in <a href="3-ta.html#SP4">&#167;4</a>.</li></ul><p class="inwebparagraph"><a id="SP4_3"></a><b>&#167;4.3. </b><code class="display">
&lt;<span class="named-paragraph-defn">Perform analysis on the body of the definition</span> <span class="named-paragraph-number">4.3</span>&gt; =
</code></p>
<pre class="displayed-code all-displayed-code">
<span class="plain-syntax"> </span><a href="3-ta.html#SP5" class="internal">Analyser::analyse_as_code</a><span class="plain-syntax">(</span><span class="identifier-syntax">W</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">text_operand2</span><span class="plain-syntax">, </span><span class="constant-syntax">ANY_USAGE</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">while</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">L</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">next_line</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">L</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">next_line</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">category</span><span class="plain-syntax"> == </span><span class="constant-syntax">CONT_DEFINITION_LCAT</span><span class="plain-syntax">)) {</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">next_line</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><a href="3-ta.html#SP5" class="internal">Analyser::analyse_as_code</a><span class="plain-syntax">(</span><span class="identifier-syntax">W</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">text</span><span class="plain-syntax">, </span><span class="constant-syntax">ANY_USAGE</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
</pre><ul class="endnotetexts"><li>This code is used in <a href="3-ta.html#SP4">&#167;4</a>.</li></ul><p class="inwebparagraph"><a id="SP4_4"></a><b>&#167;4.4. </b>Lines in a Preform grammar generally take the form of some BNF grammar, where
we want only to identify any nonterminals mentioned, then a <code class="display"><span class="extract-syntax">==&gt;</span></code> divider,
and then some C code to deal with a match. The code is subjected to analysis
just as any other code would be.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="named-paragraph-defn">Perform analysis on productions in a Preform grammar</span> <span class="named-paragraph-number">4.4</span>&gt; =
</code></p>
<pre class="displayed-code all-displayed-code">
<span class="plain-syntax"> </span><a href="3-ta.html#SP5" class="internal">Analyser::analyse_as_code</a><span class="plain-syntax">(</span><span class="identifier-syntax">W</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">text_operand2</span><span class="plain-syntax">, </span><span class="constant-syntax">ANY_USAGE</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="3-ta.html#SP5" class="internal">Analyser::analyse_as_code</a><span class="plain-syntax">(</span><span class="identifier-syntax">W</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">text_operand</span><span class="plain-syntax">, </span><span class="constant-syntax">PREFORM_IN_CODE_USAGE</span><span class="plain-syntax">, </span><span class="constant-syntax">PREFORM_IN_GRAMMAR_USAGE</span><span class="plain-syntax">);</span>
</pre><ul class="endnotetexts"><li>This code is used in <a href="3-ta.html#SP4">&#167;4</a>.</li></ul><p class="inwebparagraph"><a id="SP5"></a><b>&#167;5. Identifier searching. </b>Here's what we actually do, then. We take the code fragment <code class="display"><span class="extract-syntax">text</span></code>, drawn
from part or all of source line <code class="display"><span class="extract-syntax">L</span></code> from web <code class="display"><span class="extract-syntax">W</span></code>, and look for any identifier
names used in one of the contexts in the bitmap <code class="display"><span class="extract-syntax">mask</span></code>. Any that we find are
passed to <code class="display"><span class="extract-syntax">Analyser::analyse_find</span></code>, along with the context they were found in (or, if
<code class="display"><span class="extract-syntax">transf</span></code> is nonzero, with <code class="display"><span class="extract-syntax">transf</span></code> as their context).
</p>
<p class="inwebparagraph">What we do is to look for instances of an identifier, defined as a maximal
string of <code class="display"><span class="extract-syntax">%i</span></code> characters or hyphens not followed by <code class="display"><span class="extract-syntax">&gt;</span></code> characters. (Thus
<code class="display"><span class="extract-syntax">fish-or-chips</span></code> counts, but <code class="display"><span class="extract-syntax">fish-</span></code> is not an identifier when it occurs in
<code class="display"><span class="extract-syntax">fish-&gt;bone</span></code>.)
</p>
<pre class="displayed-code all-displayed-code">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Analyser::analyse_as_code</span><button class="popup" onclick="togglePopup('usagePopup4')">...<span class="popuptext" id="usagePopup4">Usage of <b>Analyser::analyse_as_code</b>:<br><a href="3-ta.html#SP4_2">&#167;4.2</a>, <a href="3-ta.html#SP4_3">&#167;4.3</a>, <a href="3-ta.html#SP4_4">&#167;4.4</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">web</span><span class="plain-syntax"> *</span><span class="identifier-syntax">W</span><span class="plain-syntax">, </span><span class="reserved-syntax">source_line</span><span class="plain-syntax"> *</span><span class="identifier-syntax">L</span><span class="plain-syntax">, </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">text</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">mask</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">transf</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">start_at</span><span class="plain-syntax"> = -1, </span><span class="identifier-syntax">element_follows</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">for</span><span class="plain-syntax"> (</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">; </span><span class="identifier-syntax">i</span><span class="plain-syntax"> &lt; </span><a href="../foundation-module/4-sm.html#SP8" class="internal">Str::len</a><span class="plain-syntax">(</span><span class="identifier-syntax">text</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">if</span><span class="plain-syntax"> ((</span><a href="../foundation-module/4-pm.html#SP2" class="internal">Regexp::identifier_char</a><span class="plain-syntax">(</span><a href="../foundation-module/4-sm.html#SP13" class="internal">Str::get_at</a><span class="plain-syntax">(</span><span class="identifier-syntax">text</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">))) ||</span>
<span class="plain-syntax"> ((</span><a href="../foundation-module/4-sm.html#SP13" class="internal">Str::get_at</a><span class="plain-syntax">(</span><span class="identifier-syntax">text</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">) == </span><span class="character-syntax">'-'</span><span class="plain-syntax">) &amp;&amp; (</span><a href="../foundation-module/4-sm.html#SP13" class="internal">Str::get_at</a><span class="plain-syntax">(</span><span class="identifier-syntax">text</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">+1) != </span><span class="character-syntax">'&gt;'</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">start_at</span><span class="plain-syntax"> == -1) </span><span class="identifier-syntax">start_at</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">else</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">start_at</span><span class="plain-syntax"> != -1) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">u</span><span class="plain-syntax"> = </span><span class="constant-syntax">MISC_USAGE</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">element_follows</span><span class="plain-syntax">) </span><span class="identifier-syntax">u</span><span class="plain-syntax"> = </span><span class="constant-syntax">ELEMENT_ACCESS_USAGE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="../foundation-module/4-sm.html#SP13" class="internal">Str::get_at</a><span class="plain-syntax">(</span><span class="identifier-syntax">text</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">) == </span><span class="character-syntax">'('</span><span class="plain-syntax">) </span><span class="identifier-syntax">u</span><span class="plain-syntax"> = </span><span class="constant-syntax">FCALL_USAGE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><a href="../foundation-module/4-sm.html#SP13" class="internal">Str::get_at</a><span class="plain-syntax">(</span><span class="identifier-syntax">text</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">) == </span><span class="character-syntax">'&gt;'</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">start_at</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) &amp;&amp; (</span><a href="../foundation-module/4-sm.html#SP13" class="internal">Str::get_at</a><span class="plain-syntax">(</span><span class="identifier-syntax">text</span><span class="plain-syntax">, </span><span class="identifier-syntax">start_at</span><span class="plain-syntax">-1) == </span><span class="character-syntax">'&lt;'</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">u</span><span class="plain-syntax"> = </span><span class="constant-syntax">PREFORM_IN_CODE_USAGE</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">u</span><span class="plain-syntax"> &amp; </span><span class="identifier-syntax">mask</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">transf</span><span class="plain-syntax">) </span><span class="identifier-syntax">u</span><span class="plain-syntax"> = </span><span class="identifier-syntax">transf</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">TEMPORARY_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">identifier_found</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">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">j</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">; </span><span class="identifier-syntax">start_at</span><span class="plain-syntax"> + </span><span class="identifier-syntax">j</span><span class="plain-syntax"> &lt; </span><span class="identifier-syntax">i</span><span class="plain-syntax">; </span><span class="identifier-syntax">j</span><span class="plain-syntax">++)</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">PUT_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">identifier_found</span><span class="plain-syntax">, </span><a href="../foundation-module/4-sm.html#SP13" class="internal">Str::get_at</a><span class="plain-syntax">(</span><span class="identifier-syntax">text</span><span class="plain-syntax">, </span><span class="identifier-syntax">start_at</span><span class="plain-syntax"> + </span><span class="identifier-syntax">j</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><a href="3-ta.html#SP12" class="internal">Analyser::analyse_find</a><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">, </span><span class="identifier-syntax">L</span><span class="plain-syntax">, </span><span class="identifier-syntax">identifier_found</span><span class="plain-syntax">, </span><span class="identifier-syntax">u</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">identifier_found</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">start_at</span><span class="plain-syntax"> = -1; </span><span class="identifier-syntax">element_follows</span><span class="plain-syntax"> = </span><span class="constant-syntax">FALSE</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><a href="../foundation-module/4-sm.html#SP13" class="internal">Str::get_at</a><span class="plain-syntax">(</span><span class="identifier-syntax">text</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">) == </span><span class="character-syntax">'.'</span><span class="plain-syntax">) </span><span class="identifier-syntax">element_follows</span><span class="plain-syntax"> = </span><span class="constant-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><a href="../foundation-module/4-sm.html#SP13" class="internal">Str::get_at</a><span class="plain-syntax">(</span><span class="identifier-syntax">text</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">) == </span><span class="character-syntax">'-'</span><span class="plain-syntax">) &amp;&amp; (</span><a href="../foundation-module/4-sm.html#SP13" class="internal">Str::get_at</a><span class="plain-syntax">(</span><span class="identifier-syntax">text</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">+1) == </span><span class="character-syntax">'&gt;'</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">element_follows</span><span class="plain-syntax"> = </span><span class="constant-syntax">TRUE</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">else</span><span class="plain-syntax"> </span><span class="identifier-syntax">element_follows</span><span class="plain-syntax"> = </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax">}</span>
</pre><p class="inwebparagraph"><a id="SP6"></a><b>&#167;6. The identifier hash table. </b>We clearly need rapid access to a large symbols table, and we store this as
a hash. Identifiers are hash-coded with the following simple code, which is
simplified from one used by Inform; it's the algorithm called "X 30011"
in Aho, Sethi and Ullman, "Compilers: Principles, Techniques and Tools"
(1986), adapted slightly to separate out literal numbers.
</p>
<pre class="definitions">
<span class="definition-keyword">define</span> <span class="constant-syntax">HASH_TAB_SIZE</span><span class="plain-syntax"> </span><span class="constant-syntax">1000</span><span class="plain-syntax"> </span><span class="comment"> the possible hash codes are 0 up to this minus 1</span>
<span class="definition-keyword">define</span> <span class="constant-syntax">NUMBER_HASH</span><span class="plain-syntax"> </span><span class="constant-syntax">0</span><span class="plain-syntax"> </span><span class="comment"> literal decimal integers, and no other words, have this hash code</span>
</pre>
<pre class="displayed-code all-displayed-code">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Analyser::hash_code_from_word</span><button class="popup" onclick="togglePopup('usagePopup5')">...<span class="popuptext" id="usagePopup5">Usage of <b>Analyser::hash_code_from_word</b>:<br><a href="3-ta.html#SP9">&#167;9</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">text</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">unsigned</span><span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">hash_code</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">string_position</span><span class="plain-syntax"> </span><span class="identifier-syntax">p</span><span class="plain-syntax"> = </span><a href="../foundation-module/4-sm.html#SP10" class="internal">Str::start</a><span class="plain-syntax">(</span><span class="identifier-syntax">text</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">switch</span><span class="plain-syntax">(</span><a href="../foundation-module/4-sm.html#SP13" class="internal">Str::get</a><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">case</span><span class="plain-syntax"> </span><span class="character-syntax">'-'</span><span class="plain-syntax">: </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="../foundation-module/4-sm.html#SP8" class="internal">Str::len</a><span class="plain-syntax">(</span><span class="identifier-syntax">text</span><span class="plain-syntax">) == </span><span class="constant-syntax">1</span><span class="plain-syntax">) </span><span class="reserved-syntax">break</span><span class="plain-syntax">; /* </span><span class="identifier-syntax">an</span><span class="plain-syntax"> </span><span class="identifier-syntax">isolated</span><span class="plain-syntax"> </span><span class="identifier-syntax">minus</span><span class="plain-syntax"> </span><span class="identifier-syntax">sign</span><span class="plain-syntax"> </span><span class="identifier-syntax">is</span><span class="plain-syntax"> </span><span class="identifier-syntax">an</span><span class="plain-syntax"> </span><span class="identifier-syntax">ordinary</span><span class="plain-syntax"> </span><span class="identifier-syntax">word</span><span class="plain-syntax"> */</span>
<span class="plain-syntax"> </span><span class="comment"> and otherwise fall into...</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="character-syntax">'0'</span><span class="plain-syntax">: </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="character-syntax">'1'</span><span class="plain-syntax">: </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="character-syntax">'2'</span><span class="plain-syntax">: </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="character-syntax">'3'</span><span class="plain-syntax">: </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="character-syntax">'4'</span><span class="plain-syntax">:</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="character-syntax">'5'</span><span class="plain-syntax">: </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="character-syntax">'6'</span><span class="plain-syntax">: </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="character-syntax">'7'</span><span class="plain-syntax">: </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="character-syntax">'8'</span><span class="plain-syntax">: </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="character-syntax">'9'</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">numeric</span><span class="plain-syntax"> = </span><span class="constant-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="comment"> the first character may prove to be the start of a number: is this true?</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">p</span><span class="plain-syntax"> = </span><a href="../foundation-module/4-sm.html#SP11" class="internal">Str::forward</a><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">); </span><a href="../foundation-module/4-sm.html#SP11" class="internal">Str::in_range</a><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">); </span><span class="identifier-syntax">p</span><span class="plain-syntax"> = </span><a href="../foundation-module/4-sm.html#SP11" class="internal">Str::forward</a><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">isdigit</span><span class="plain-syntax">(</span><a href="../foundation-module/4-sm.html#SP13" class="internal">Str::get</a><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="identifier-syntax">numeric</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">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">numeric</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">NUMBER_HASH</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="identifier-syntax">p</span><span class="plain-syntax">=</span><a href="../foundation-module/4-sm.html#SP10" class="internal">Str::start</a><span class="plain-syntax">(</span><span class="identifier-syntax">text</span><span class="plain-syntax">); </span><a href="../foundation-module/4-sm.html#SP11" class="internal">Str::in_range</a><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">); </span><span class="identifier-syntax">p</span><span class="plain-syntax"> = </span><a href="../foundation-module/4-sm.html#SP11" class="internal">Str::forward</a><span class="plain-syntax">(</span><span class="identifier-syntax">p</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">hash_code</span><span class="plain-syntax"> = (</span><span class="reserved-syntax">unsigned</span><span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax">) ((</span><span class="reserved-syntax">int</span><span class="plain-syntax">) (</span><span class="identifier-syntax">hash_code</span><span class="plain-syntax">*30011) + (</span><a href="../foundation-module/4-sm.html#SP13" class="internal">Str::get</a><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">return</span><span class="plain-syntax"> (</span><span class="reserved-syntax">int</span><span class="plain-syntax">) (1+(</span><span class="identifier-syntax">hash_code</span><span class="plain-syntax"> % (</span><span class="constant-syntax">HASH_TAB_SIZE</span><span class="plain-syntax">-1))); </span><span class="comment"> result of X 30011, plus 1</span>
<span class="plain-syntax">}</span>
</pre><p class="inwebparagraph"><a id="SP7"></a><b>&#167;7. </b>The actual table is stored here:
</p>
<pre class="displayed-code all-displayed-code">
<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">hash_table</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</span><span class="plain-syntax"> *</span><span class="identifier-syntax">analysis_hash</span><span class="plain-syntax">[</span><span class="constant-syntax">HASH_TAB_SIZE</span><span class="plain-syntax">]; </span><span class="comment"> of </span><code class="display"><span class="extract-syntax">hash_table_entry</span></code>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">analysis_hash_initialised</span><span class="plain-syntax">; </span><span class="comment"> when we start up, array's contents are undefined</span>
<span class="plain-syntax">} </span><span class="reserved-syntax">hash_table</span><span class="plain-syntax">;</span>
</pre><ul class="endnotetexts"><li>The structure hash_table is accessed in 2/tr, 4/pl and here.</li></ul><p class="inwebparagraph"><a id="SP8"></a><b>&#167;8. </b>Where we define:
</p>
<pre class="displayed-code all-displayed-code">
<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">hash_table_entry</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">hash_key</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="reserved-syntax">reserved_word</span><span class="plain-syntax">; </span><span class="comment"> in the language currently being woven, that is</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="identifier-syntax">usages</span><span class="plain-syntax">; </span><span class="comment"> of </span><code class="display"><span class="extract-syntax">hash_table_entry_usage</span></code>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">source_line</span><span class="plain-syntax"> *</span><span class="identifier-syntax">definition_line</span><span class="plain-syntax">; </span><span class="comment"> or null, if it's not a constant, function or type name</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">language_function</span><span class="plain-syntax"> *</span><span class="identifier-syntax">as_function</span><span class="plain-syntax">; </span><span class="comment"> for function names only</span>
<span class="plain-syntax"> </span><span class="constant-syntax">MEMORY_MANAGEMENT</span>
<span class="plain-syntax">} </span><span class="reserved-syntax">hash_table_entry</span><span class="plain-syntax">;</span>
</pre><ul class="endnotetexts"><li>The structure hash_table_entry is accessed in 3/tw, 4/taf, 4/as, 4/is, 5/tf and here.</li></ul><p class="inwebparagraph"><a id="SP9"></a><b>&#167;9. </b>A single routine is used both to interrogate the hash and to lodge values
in it, as usual with symbols tables. For example, the code to handle C-like
languages prepares for code analysis by calling this routine on the name
of each C function.
</p>
<pre class="displayed-code all-displayed-code">
<span class="reserved-syntax">hash_table_entry</span><span class="plain-syntax"> *</span><span class="function-syntax">Analyser::find_hash_entry</span><button class="popup" onclick="togglePopup('usagePopup6')">...<span class="popuptext" id="usagePopup6">Usage of <b>Analyser::find_hash_entry</b>:<br><a href="3-ta.html#SP10">&#167;10</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">hash_table</span><span class="plain-syntax"> *</span><span class="identifier-syntax">HT</span><span class="plain-syntax">, </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">text</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">create</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">h</span><span class="plain-syntax"> = </span><a href="3-ta.html#SP6" class="internal">Analyser::hash_code_from_word</a><span class="plain-syntax">(</span><span class="identifier-syntax">text</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">h</span><span class="plain-syntax"> == </span><span class="constant-syntax">NUMBER_HASH</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">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">HT</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">analysis_hash_initialised</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">for</span><span class="plain-syntax"> (</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax">=0; </span><span class="identifier-syntax">i</span><span class="plain-syntax">&lt;</span><span class="constant-syntax">HASH_TAB_SIZE</span><span class="plain-syntax">; </span><span class="identifier-syntax">i</span><span class="plain-syntax">++) </span><span class="identifier-syntax">HT</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">analysis_hash</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</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">HT</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">analysis_hash_initialised</span><span class="plain-syntax"> = </span><span class="constant-syntax">TRUE</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">HT</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">analysis_hash</span><span class="plain-syntax">[</span><span class="identifier-syntax">h</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">hash_table_entry</span><span class="plain-syntax"> *</span><span class="identifier-syntax">hte</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">LOOP_OVER_LINKED_LIST</span><span class="plain-syntax">(</span><span class="identifier-syntax">hte</span><span class="plain-syntax">, </span><span class="reserved-syntax">hash_table_entry</span><span class="plain-syntax">, </span><span class="identifier-syntax">HT</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">analysis_hash</span><span class="plain-syntax">[</span><span class="identifier-syntax">h</span><span class="plain-syntax">])</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="../foundation-module/4-sm.html#SP19" class="internal">Str::eq</a><span class="plain-syntax">(</span><span class="identifier-syntax">hte</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">hash_key</span><span class="plain-syntax">, </span><span class="identifier-syntax">text</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">hte</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">create</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">hash_table_entry</span><span class="plain-syntax"> *</span><span class="identifier-syntax">hte</span><span class="plain-syntax"> = </span><span class="identifier-syntax">CREATE</span><span class="plain-syntax">(</span><span class="reserved-syntax">hash_table_entry</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">hte</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">hash_key</span><span class="plain-syntax"> = </span><a href="../foundation-module/4-sm.html#SP3" class="internal">Str::duplicate</a><span class="plain-syntax">(</span><span class="identifier-syntax">text</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">hte</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">usages</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NEW_LINKED_LIST</span><span class="plain-syntax">(</span><span class="reserved-syntax">hash_table_entry_usage</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">HT</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">analysis_hash</span><span class="plain-syntax">[</span><span class="identifier-syntax">h</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">HT</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">analysis_hash</span><span class="plain-syntax">[</span><span class="identifier-syntax">h</span><span class="plain-syntax">] = </span><span class="identifier-syntax">NEW_LINKED_LIST</span><span class="plain-syntax">(</span><span class="reserved-syntax">hash_table_entry</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">ADD_TO_LINKED_LIST</span><span class="plain-syntax">(</span><span class="identifier-syntax">hte</span><span class="plain-syntax">, </span><span class="reserved-syntax">hash_table_entry</span><span class="plain-syntax">, </span><span class="identifier-syntax">HT</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">analysis_hash</span><span class="plain-syntax">[</span><span class="identifier-syntax">h</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">hte</span><span class="plain-syntax">;</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">hash_table_entry</span><span class="plain-syntax"> *</span><span class="function-syntax">Analyser::find_hash_entry_for_section</span><button class="popup" onclick="togglePopup('usagePopup7')">...<span class="popuptext" id="usagePopup7">Usage of <b>Analyser::find_hash_entry_for_section</b>:<br><a href="3-ta.html#SP12">&#167;12</a>, The Weaver - <a href="3-tw.html#SP3_3">&#167;3.3</a>, <a href="3-tw.html#SP4">&#167;4</a>&lt;br&gt;ACME Support - <a href="4-as.html#SP6">&#167;6</a>, <a href="4-as.html#SP7">&#167;7</a>&lt;br&gt;InC Support - <a href="4-is.html#SP14_1">&#167;14.1</a>, <a href="4-is.html#SP14_2">&#167;14.2</a>, <a href="4-is.html#SP18">&#167;18</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">section</span><span class="plain-syntax"> *</span><span class="identifier-syntax">S</span><span class="plain-syntax">, </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">text</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">create</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><a href="3-ta.html#SP9" class="internal">Analyser::find_hash_entry</a><span class="plain-syntax">(&amp;(</span><span class="identifier-syntax">S</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">sect_target</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">symbols</span><span class="plain-syntax">), </span><span class="identifier-syntax">text</span><span class="plain-syntax">, </span><span class="identifier-syntax">create</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre><p class="inwebparagraph"><a id="SP10"></a><b>&#167;10. </b>Marking and testing these bits:
</p>
<pre class="displayed-code all-displayed-code">
<span class="reserved-syntax">hash_table_entry</span><span class="plain-syntax"> *</span><span class="function-syntax">Analyser::mark_reserved_word</span><button class="popup" onclick="togglePopup('usagePopup8')">...<span class="popuptext" id="usagePopup8">Usage of <b>Analyser::mark_reserved_word</b>:<br>Programming Languages - <a href="4-pl.html#SP14">&#167;14</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">hash_table</span><span class="plain-syntax"> *</span><span class="identifier-syntax">HT</span><span class="plain-syntax">, </span><span class="reserved-syntax">text_stream</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">e</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">hash_table_entry</span><span class="plain-syntax"> *</span><span class="identifier-syntax">hte</span><span class="plain-syntax"> = </span><a href="3-ta.html#SP9" class="internal">Analyser::find_hash_entry</a><span class="plain-syntax">(</span><span class="identifier-syntax">HT</span><span class="plain-syntax">, </span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="constant-syntax">TRUE</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">hte</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">reserved_word</span><span class="plain-syntax"> |= (1 &lt;&lt; </span><span class="identifier-syntax">e</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">hte</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">definition_line</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">hte</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">as_function</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">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">hte</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">Analyser::mark_reserved_word_for_section</span><button class="popup" onclick="togglePopup('usagePopup9')">...<span class="popuptext" id="usagePopup9">Usage of <b>Analyser::mark_reserved_word_for_section</b>:<br>ACME Support - <a href="4-as.html#SP9">&#167;9</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">section</span><span class="plain-syntax"> *</span><span class="identifier-syntax">S</span><span class="plain-syntax">, </span><span class="reserved-syntax">text_stream</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">e</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><a href="3-ta.html#SP10" class="internal">Analyser::mark_reserved_word</a><span class="plain-syntax">(&amp;(</span><span class="identifier-syntax">S</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">sect_target</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">symbols</span><span class="plain-syntax">), </span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="identifier-syntax">e</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">hash_table_entry</span><span class="plain-syntax"> *</span><span class="function-syntax">Analyser::mark_reserved_word_at_line</span><button class="popup" onclick="togglePopup('usagePopup10')">...<span class="popuptext" id="usagePopup10">Usage of <b>Analyser::mark_reserved_word_at_line</b>:<br>The Parser - <a href="2-tp.html#SP1_1_7_5_1_6">&#167;1.1.7.5.1.6</a>, <a href="2-tp.html#SP1_1_7_5_1_7">&#167;1.1.7.5.1.7</a>&lt;br&gt;Types and Functions - <a href="4-taf.html#SP2">&#167;2</a>, <a href="4-taf.html#SP4">&#167;4</a>, <a href="4-taf.html#SP7">&#167;7</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">source_line</span><span class="plain-syntax"> *</span><span class="identifier-syntax">L</span><span class="plain-syntax">, </span><span class="reserved-syntax">text_stream</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">e</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">"no line for rw"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">hash_table_entry</span><span class="plain-syntax"> *</span><span class="identifier-syntax">hte</span><span class="plain-syntax"> =</span>
<span class="plain-syntax"> </span><a href="3-ta.html#SP10" class="internal">Analyser::mark_reserved_word</a><span class="plain-syntax">(&amp;(</span><span class="identifier-syntax">L</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">owning_section</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">sect_target</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">symbols</span><span class="plain-syntax">), </span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="identifier-syntax">e</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">hte</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">definition_line</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">hte</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Analyser::is_reserved_word</span><button class="popup" onclick="togglePopup('usagePopup11')">...<span class="popuptext" id="usagePopup11">Usage of <b>Analyser::is_reserved_word</b>:<br>The Painter - <a href="4-tp.html#SP5">&#167;5</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">hash_table</span><span class="plain-syntax"> *</span><span class="identifier-syntax">HT</span><span class="plain-syntax">, </span><span class="reserved-syntax">text_stream</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">e</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">hash_table_entry</span><span class="plain-syntax"> *</span><span class="identifier-syntax">hte</span><span class="plain-syntax"> = </span><a href="3-ta.html#SP9" class="internal">Analyser::find_hash_entry</a><span class="plain-syntax">(</span><span class="identifier-syntax">HT</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">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">hte</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">hte</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">reserved_word</span><span class="plain-syntax"> &amp; (1 &lt;&lt; </span><span class="identifier-syntax">e</span><span class="plain-syntax">))) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</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">int</span><span class="plain-syntax"> </span><span class="function-syntax">Analyser::is_reserved_word_for_section</span><button class="popup" onclick="togglePopup('usagePopup12')">...<span class="popuptext" id="usagePopup12">Usage of <b>Analyser::is_reserved_word_for_section</b>:<br>The Weaver of Text - <a href="3-twot.html#SP3">&#167;3</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">section</span><span class="plain-syntax"> *</span><span class="identifier-syntax">S</span><span class="plain-syntax">, </span><span class="reserved-syntax">text_stream</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">e</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><a href="3-ta.html#SP10" class="internal">Analyser::is_reserved_word</a><span class="plain-syntax">(&amp;(</span><span class="identifier-syntax">S</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">sect_target</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">symbols</span><span class="plain-syntax">), </span><span class="identifier-syntax">p</span><span class="plain-syntax">, </span><span class="identifier-syntax">e</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
<span class="reserved-syntax">source_line</span><span class="plain-syntax"> *</span><span class="function-syntax">Analyser::get_defn_line</span><button class="popup" onclick="togglePopup('usagePopup13')">...<span class="popuptext" id="usagePopup13">Usage of <b>Analyser::get_defn_line</b>:<br>none</span></button><span class="plain-syntax">(</span><span class="reserved-syntax">section</span><span class="plain-syntax"> *</span><span class="identifier-syntax">S</span><span class="plain-syntax">, </span><span class="reserved-syntax">text_stream</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">e</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">hash_table_entry</span><span class="plain-syntax"> *</span><span class="identifier-syntax">hte</span><span class="plain-syntax"> = </span><a href="3-ta.html#SP9" class="internal">Analyser::find_hash_entry</a><span class="plain-syntax">(&amp;(</span><span class="identifier-syntax">S</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">sect_target</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">symbols</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">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">hte</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">hte</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">reserved_word</span><span class="plain-syntax"> &amp; (1 &lt;&lt; </span><span class="identifier-syntax">e</span><span class="plain-syntax">))) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">hte</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">definition_line</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">language_function</span><span class="plain-syntax"> *</span><span class="function-syntax">Analyser::get_function</span><button class="popup" onclick="togglePopup('usagePopup14')">...<span class="popuptext" id="usagePopup14">Usage of <b>Analyser::get_function</b>:<br>The Weaver of Text - <a href="3-twot.html#SP3_3">&#167;3.3</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">section</span><span class="plain-syntax"> *</span><span class="identifier-syntax">S</span><span class="plain-syntax">, </span><span class="reserved-syntax">text_stream</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">e</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">hash_table_entry</span><span class="plain-syntax"> *</span><span class="identifier-syntax">hte</span><span class="plain-syntax"> = </span><a href="3-ta.html#SP9" class="internal">Analyser::find_hash_entry</a><span class="plain-syntax">(&amp;(</span><span class="identifier-syntax">S</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">sect_target</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">symbols</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">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">hte</span><span class="plain-syntax">) &amp;&amp; (</span><span class="identifier-syntax">hte</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">reserved_word</span><span class="plain-syntax"> &amp; (1 &lt;&lt; </span><span class="identifier-syntax">e</span><span class="plain-syntax">))) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">hte</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">as_function</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="inwebparagraph"><a id="SP11"></a><b>&#167;11. </b>Now we turn back to the actual analysis. When we spot an identifier that
we know, we record its usage with an instance of the following. Note that
each identifier can have at most one of these records per paragraph of code,
but that it can be used in multiple ways within that paragraph: for example,
a function might be both called and used as a constant value within the
same paragraph of code.
</p>
<pre class="displayed-code all-displayed-code">
<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">hash_table_entry_usage</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">paragraph</span><span class="plain-syntax"> *</span><span class="identifier-syntax">usage_recorded_at</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">form_of_usage</span><span class="plain-syntax">; </span><span class="comment"> bitmap of the </span><code class="display"><span class="extract-syntax">*_USAGE</span></code><span class="comment"> constants defined above</span>
<span class="plain-syntax"> </span><span class="constant-syntax">MEMORY_MANAGEMENT</span>
<span class="plain-syntax">} </span><span class="reserved-syntax">hash_table_entry_usage</span><span class="plain-syntax">;</span>
</pre><ul class="endnotetexts"><li>The structure hash_table_entry_usage is accessed in 3/tw, 4/as, 4/is and here.</li></ul><p class="inwebparagraph"><a id="SP12"></a><b>&#167;12. </b>And here's how we create these usages:
</p>
<pre class="displayed-code all-displayed-code">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Analyser::analyse_find</span><button class="popup" onclick="togglePopup('usagePopup15')">...<span class="popuptext" id="usagePopup15">Usage of <b>Analyser::analyse_find</b>:<br><a href="3-ta.html#SP5">&#167;5</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">web</span><span class="plain-syntax"> *</span><span class="identifier-syntax">W</span><span class="plain-syntax">, </span><span class="reserved-syntax">source_line</span><span class="plain-syntax"> *</span><span class="identifier-syntax">L</span><span class="plain-syntax">, </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">identifier</span><span class="plain-syntax">, </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">u</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">hash_table_entry</span><span class="plain-syntax"> *</span><span class="identifier-syntax">hte</span><span class="plain-syntax"> =</span>
<span class="plain-syntax"> </span><a href="3-ta.html#SP9" class="internal">Analyser::find_hash_entry_for_section</a><span class="plain-syntax">(</span><span class="identifier-syntax">L</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">owning_section</span><span class="plain-syntax">, </span><span class="identifier-syntax">identifier</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">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">hte</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</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">hash_table_entry_usage</span><span class="plain-syntax"> *</span><span class="identifier-syntax">hteu</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">LOOP_OVER_LINKED_LIST</span><span class="plain-syntax">(</span><span class="identifier-syntax">hteu</span><span class="plain-syntax">, </span><span class="reserved-syntax">hash_table_entry_usage</span><span class="plain-syntax">, </span><span class="identifier-syntax">hte</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">usages</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">owning_paragraph</span><span class="plain-syntax"> == </span><span class="identifier-syntax">hteu</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">usage_recorded_at</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">break</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">hteu</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">hteu</span><span class="plain-syntax"> = </span><span class="identifier-syntax">CREATE</span><span class="plain-syntax">(</span><span class="reserved-syntax">hash_table_entry_usage</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">hteu</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">form_of_usage</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">hteu</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">usage_recorded_at</span><span class="plain-syntax"> = </span><span class="identifier-syntax">L</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">owning_paragraph</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">ADD_TO_LINKED_LIST</span><span class="plain-syntax">(</span><span class="identifier-syntax">hteu</span><span class="plain-syntax">, </span><span class="reserved-syntax">hash_table_entry_usage</span><span class="plain-syntax">, </span><span class="identifier-syntax">hte</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">usages</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">hteu</span><span class="plain-syntax">-&gt;</span><span class="identifier-syntax">form_of_usage</span><span class="plain-syntax"> |= </span><span class="identifier-syntax">u</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre><p class="inwebparagraph"><a id="SP13"></a><b>&#167;13. Open-source project support. </b>The work here is all delegated. In each case we look for a script in the web's
folder: failing that, we fall back on a default script belonging to Inweb.
</p>
<pre class="displayed-code all-displayed-code">
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Analyser::write_makefile</span><button class="popup" onclick="togglePopup('usagePopup16')">...<span class="popuptext" id="usagePopup16">Usage of <b>Analyser::write_makefile</b>:<br>Program Control - <a href="1-pc.html#SP7_4_1">&#167;7.4.1</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">web</span><span class="plain-syntax"> *</span><span class="identifier-syntax">W</span><span class="plain-syntax">, </span><span class="reserved-syntax">filename</span><span class="plain-syntax"> *</span><span class="identifier-syntax">F</span><span class="plain-syntax">, </span><span class="reserved-syntax">module_search</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">filename</span><span class="plain-syntax"> *</span><span class="identifier-syntax">prototype</span><span class="plain-syntax"> = </span><a href="../foundation-module/3-fln.html#SP2" class="internal">Filenames::in</a><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">md</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">path_to_web</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"makescript.txt"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (!(</span><a href="../foundation-module/4-tf.html#SP1" class="internal">TextFiles::exists</a><span class="plain-syntax">(</span><span class="identifier-syntax">prototype</span><span class="plain-syntax">)))</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">prototype</span><span class="plain-syntax"> = </span><a href="../foundation-module/3-fln.html#SP2" class="internal">Filenames::in</a><span class="plain-syntax">(</span><span class="identifier-syntax">path_to_inweb_materials</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"makescript.txt"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="6-mkf.html#SP1" class="internal">Makefiles::write</a><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">, </span><span class="identifier-syntax">prototype</span><span class="plain-syntax">, </span><span class="identifier-syntax">F</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">void</span><span class="plain-syntax"> </span><span class="function-syntax">Analyser::write_gitignore</span><button class="popup" onclick="togglePopup('usagePopup17')">...<span class="popuptext" id="usagePopup17">Usage of <b>Analyser::write_gitignore</b>:<br>Program Control - <a href="1-pc.html#SP7_4_1">&#167;7.4.1</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">web</span><span class="plain-syntax"> *</span><span class="identifier-syntax">W</span><span class="plain-syntax">, </span><span class="reserved-syntax">filename</span><span class="plain-syntax"> *</span><span class="identifier-syntax">F</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">filename</span><span class="plain-syntax"> *</span><span class="identifier-syntax">prototype</span><span class="plain-syntax"> = </span><a href="../foundation-module/3-fln.html#SP2" class="internal">Filenames::in</a><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">md</span><span class="plain-syntax">-&gt;</span><span class="element-syntax">path_to_web</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"gitignorescript.txt"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (!(</span><a href="../foundation-module/4-tf.html#SP1" class="internal">TextFiles::exists</a><span class="plain-syntax">(</span><span class="identifier-syntax">prototype</span><span class="plain-syntax">)))</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">prototype</span><span class="plain-syntax"> = </span><a href="../foundation-module/3-fln.html#SP2" class="internal">Filenames::in</a><span class="plain-syntax">(</span><span class="identifier-syntax">path_to_inweb_materials</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"gitignorescript.txt"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><a href="6-gs.html#SP1" class="internal">Git::write_gitignore</a><span class="plain-syntax">(</span><span class="identifier-syntax">W</span><span class="plain-syntax">, </span><span class="identifier-syntax">prototype</span><span class="plain-syntax">, </span><span class="identifier-syntax">F</span><span class="plain-syntax">);</span>
<span class="plain-syntax">}</span>
</pre><hr class="tocbar">
<ul class="toc"><li><i>(This section begins Chapter 3: Outputs.)</i></li><li><a href="3-ti.html">Continue with 'The Indexer'</a></li></ul><hr class="tocbar">
<!--End of weave-->
</main>
</body>
</html>