inweb-bootstrap/docs/inweb/2-mdl.html

224 lines
20 KiB
HTML
Raw Normal View History

2019-02-04 22:26:45 +00:00
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>2/tr</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="Content-Language" content="en-gb">
<link href="inweb.css" rel="stylesheet" rev="stylesheet" type="text/css">
</head>
<body>
2019-02-09 12:33:40 +00:00
<!--Weave of '2/mdl' generated by 7-->
2019-02-04 22:26:45 +00:00
<ul class="crumbs"><li><a href="../webs.html">&#9733;</a></li><li><a href="index.html">inweb 7</a></li><li><a href="index.html#2">Chapter 2: Parsing a Web</a></li><li><b>Modules</b></li></ul><p class="purpose">To search for included modules, and track dependencies between them.</p>
<ul class="toc"><li><a href="#SP1">&#167;1. Creation</a></li><li><a href="#SP4">&#167;4. Dependencies</a></li><li><a href="#SP5">&#167;5. Searching</a></li></ul><hr class="tocbar">
<p class="inwebparagraph"><a id="SP1"></a><b>&#167;1. Creation. </b>Each web of source material discovered by Inweb is given one of the following.
Ordinarily these are found only when reading in a web for weaving, tangling
and so on: in the vast majority of Inweb runs, all modules will have the
"module origin marker" <code class="display"><span class="extract">READING_WEB_MOM</span></code>. But when Inweb is constructing a
makefile for a suite of tools, it can also discover multiple webs by other
means.
</p>
<pre class="definitions">
<span class="definitionkeyword">enum</span> <span class="constant">READING_WEB_MOM</span><span class="definitionkeyword"> from </span><span class="constant">0</span>
<span class="definitionkeyword">enum</span> <span class="constant">MAKEFILE_TOOL_MOM</span>
<span class="definitionkeyword">enum</span> <span class="constant">MAKEFILE_MODULE_MOM</span>
</pre>
<pre class="display">
<span class="reserved">typedef</span><span class="plain"> </span><span class="reserved">struct</span><span class="plain"> </span><span class="reserved">module</span><span class="plain"> {</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">pathname</span><span class="plain"> *</span><span class="identifier">module_location</span><span class="plain">;</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">module_name</span><span class="plain">;</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">linked_list</span><span class="plain"> *</span><span class="identifier">dependencies</span><span class="plain">; </span> <span class="comment">of <code class="display"><span class="extract">module</span></code>: which other modules does this need?</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">origin_marker</span><span class="plain">; </span> <span class="comment">one of the <code class="display"><span class="extract">*_MOM</span></code> values above</span>
<span class="constant">MEMORY_MANAGEMENT</span>
<span class="plain">} </span><span class="reserved">module</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The structure module is accessed in 6/mkf and here.</p>
<p class="inwebparagraph"><a id="SP2"></a><b>&#167;2. </b></p>
<pre class="display">
<span class="reserved">module</span><span class="plain"> *</span><span class="functiontext">Modules::new</span><span class="plain">(</span><span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">name</span><span class="plain">, </span><span class="reserved">pathname</span><span class="plain"> *</span><span class="identifier">at</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">m</span><span class="plain">) {</span>
<span class="reserved">module</span><span class="plain"> *</span><span class="identifier">M</span><span class="plain"> = </span><span class="identifier">CREATE</span><span class="plain">(</span><span class="reserved">module</span><span class="plain">);</span>
<span class="identifier">M</span><span class="plain">-</span><span class="element">&gt;module_location</span><span class="plain"> = </span><span class="identifier">at</span><span class="plain">;</span>
<span class="identifier">M</span><span class="plain">-</span><span class="element">&gt;module_name</span><span class="plain"> = </span><span class="functiontext">Str::duplicate</span><span class="plain">(</span><span class="identifier">name</span><span class="plain">);</span>
<span class="identifier">M</span><span class="plain">-</span><span class="element">&gt;dependencies</span><span class="plain"> = </span><span class="identifier">NEW_LINKED_LIST</span><span class="plain">(</span><span class="reserved">module</span><span class="plain">);</span>
<span class="identifier">M</span><span class="plain">-</span><span class="element">&gt;origin_marker</span><span class="plain"> = </span><span class="identifier">m</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">M</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Modules::new is used in <a href="#SP3">&#167;3</a>, <a href="#SP7_1">&#167;7.1</a>, 6/mkf (<a href="6-mkf.html#SP2_7">&#167;2.7</a>, <a href="6-mkf.html#SP2_8">&#167;2.8</a>).</p>
<p class="inwebparagraph"><a id="SP3"></a><b>&#167;3. </b>In the Inweb documentation, "module" is used to refer to a sidekick web which
contains a suite of utility routines, or a major component of a program, but
which is not a program in its own right.
</p>
<p class="inwebparagraph">Internally, though, every web produces a <code class="display"><span class="extract">module</span></code> structure. The one for the
main web &mdash; which can be tangled, and results in an actual program &mdash; is
internally named <code class="display"><span class="extract">"(main)"</span></code>, a name which the user will never see.
</p>
<pre class="display">
<span class="reserved">module</span><span class="plain"> *</span><span class="functiontext">Modules::main_module</span><span class="plain">(</span><span class="reserved">web</span><span class="plain"> *</span><span class="identifier">W</span><span class="plain">) {</span>
<span class="reserved">return</span><span class="plain"> </span><span class="functiontext">Modules::new</span><span class="plain">(</span><span class="identifier">I</span><span class="string">"(main)"</span><span class="plain">, </span><span class="identifier">W</span><span class="plain">-</span><span class="element">&gt;path_to_web</span><span class="plain">, </span><span class="constant">READING_WEB_MOM</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Modules::main_module is used in 2/tr (<a href="2-tr.html#SP2">&#167;2</a>).</p>
<p class="inwebparagraph"><a id="SP4"></a><b>&#167;4. Dependencies. </b>When web A imports module B, we will say that A is dependent on B. A web
can import multiple modules, so there can a list of dependencies. These are
needed when constructing makefiles, since the source code in B affects the
program generated by A.
</p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Modules::dependency</span><span class="plain">(</span><span class="reserved">module</span><span class="plain"> *</span><span class="identifier">A</span><span class="plain">, </span><span class="reserved">module</span><span class="plain"> *</span><span class="identifier">B</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">A</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) || (</span><span class="identifier">B</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">)) </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"no module"</span><span class="plain">);</span>
<span class="identifier">ADD_TO_LINKED_LIST</span><span class="plain">(</span><span class="identifier">B</span><span class="plain">, </span><span class="reserved">module</span><span class="plain">, </span><span class="identifier">A</span><span class="plain">-</span><span class="element">&gt;dependencies</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Modules::dependency is used in <a href="#SP7_1">&#167;7.1</a>, 6/mkf (<a href="6-mkf.html#SP2_9">&#167;2.9</a>).</p>
<p class="inwebparagraph"><a id="SP5"></a><b>&#167;5. Searching. </b>The following abstracts the idea of a place where modules might be found.
(At one time there was going to be a more elaborate search hierarchy.)
</p>
<pre class="display">
<span class="reserved">typedef</span><span class="plain"> </span><span class="reserved">struct</span><span class="plain"> </span><span class="reserved">module_search</span><span class="plain"> {</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">pathname</span><span class="plain"> *</span><span class="identifier">path_to_search</span><span class="plain">;</span>
<span class="constant">MEMORY_MANAGEMENT</span>
<span class="plain">} </span><span class="reserved">module_search</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The structure module_search is private to this section.</p>
<p class="inwebparagraph"><a id="SP6"></a><b>&#167;6. </b></p>
<pre class="display">
<span class="reserved">module_search</span><span class="plain"> *</span><span class="functiontext">Modules::make_search_path</span><span class="plain">(</span><span class="reserved">pathname</span><span class="plain"> *</span><span class="identifier">ext_path</span><span class="plain">) {</span>
<span class="reserved">module_search</span><span class="plain"> *</span><span class="identifier">ms</span><span class="plain"> = </span><span class="identifier">CREATE</span><span class="plain">(</span><span class="reserved">module_search</span><span class="plain">);</span>
<span class="identifier">ms</span><span class="plain">-</span><span class="element">&gt;path_to_search</span><span class="plain"> = </span><span class="identifier">ext_path</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">ms</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
2019-03-12 23:32:12 +00:00
<p class="endnote">The function Modules::make_search_path is used in 1/pc (<a href="1-pc.html#SP7">&#167;7</a>).</p>
2019-02-04 22:26:45 +00:00
<p class="inwebparagraph"><a id="SP7"></a><b>&#167;7. </b>When a web's contents page says to <code class="display"><span class="extract">import Blah</span></code>, how do we find the module
called <code class="display"><span class="extract">Blah</span></code> on disc? We try four possibilities in sequence:
</p>
<pre class="display">
<span class="reserved">pathname</span><span class="plain"> *</span><span class="functiontext">Modules::find</span><span class="plain">(</span><span class="reserved">web</span><span class="plain"> *</span><span class="identifier">W</span><span class="plain">, </span><span class="reserved">module_search</span><span class="plain"> *</span><span class="identifier">ms</span><span class="plain">, </span><span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">name</span><span class="plain">) {</span>
<span class="reserved">pathname</span><span class="plain"> *</span><span class="identifier">tries</span><span class="plain">[4];</span>
<span class="identifier">tries</span><span class="plain">[0] = </span><span class="identifier">W</span><span class="plain">?(</span><span class="identifier">W</span><span class="plain">-</span><span class="element">&gt;path_to_web</span><span class="plain">):</span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">tries</span><span class="plain">[1] = </span><span class="functiontext">Pathnames::up</span><span class="plain">(</span><span class="identifier">tries</span><span class="plain">[0]);</span>
2019-03-12 23:32:12 +00:00
<span class="identifier">tries</span><span class="plain">[2] = </span><span class="identifier">path_to_inweb</span><span class="plain">;</span>
2019-02-04 22:26:45 +00:00
<span class="identifier">tries</span><span class="plain">[3] = </span><span class="identifier">ms</span><span class="plain">-</span><span class="element">&gt;path_to_search</span><span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">N</span><span class="plain"> = 4;</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">i</span><span class="plain">=0; </span><span class="identifier">i</span><span class="plain">&lt;</span><span class="identifier">N</span><span class="plain">; </span><span class="identifier">i</span><span class="plain">++) {</span>
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">T</span><span class="plain">);</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">T</span><span class="plain">, </span><span class="string">"%S-module"</span><span class="plain">, </span><span class="identifier">name</span><span class="plain">);</span>
<span class="reserved">pathname</span><span class="plain"> *</span><span class="identifier">P</span><span class="plain"> = </span><span class="functiontext">Pathnames::from_text_relative</span><span class="plain">(</span><span class="identifier">tries</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">], </span><span class="identifier">T</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Modules::exists</span><span class="plain">(</span><span class="identifier">P</span><span class="plain">)) </span>&lt;<span class="cwebmacro">Accept this directory as the module</span> <span class="cwebmacronumber">7.1</span>&gt;<span class="plain">;</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">T</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Modules::find is used in 2/tr (<a href="2-tr.html#SP9_3_3_2">&#167;9.3.3.2</a>).</p>
<p class="inwebparagraph"><a id="SP7_1"></a><b>&#167;7.1. </b>When the module is found (if it is), a suitable module structure is made,
and a dependency created from the web's <code class="display"><span class="extract">(main)</span></code> module to this one.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Accept this directory as the module</span> <span class="cwebmacronumber">7.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">module</span><span class="plain"> *</span><span class="identifier">M</span><span class="plain"> = </span><span class="functiontext">Modules::new</span><span class="plain">(</span><span class="identifier">name</span><span class="plain">, </span><span class="identifier">P</span><span class="plain">, </span><span class="constant">READING_WEB_MOM</span><span class="plain">);</span>
<span class="functiontext">Modules::dependency</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">-</span><span class="element">&gt;as_module</span><span class="plain">, </span><span class="identifier">M</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">P</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP7">&#167;7</a>.</p>
<p class="inwebparagraph"><a id="SP8"></a><b>&#167;8. </b>We accept that a plausibly-named directory is indeed the module being
sought if it contains a file called <code class="display"><span class="extract">Contents.w</span></code>: it's then certainly going
to be a web of some kind.
</p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">Modules::exists</span><span class="plain">(</span><span class="reserved">pathname</span><span class="plain"> *</span><span class="identifier">P</span><span class="plain">) {</span>
<span class="reserved">filename</span><span class="plain"> *</span><span class="identifier">Contents</span><span class="plain"> = </span><span class="functiontext">Filenames::in_folder</span><span class="plain">(</span><span class="identifier">P</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Contents.w"</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="functiontext">TextFiles::exists</span><span class="plain">(</span><span class="identifier">Contents</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Modules::exists is used in <a href="#SP7">&#167;7</a>.</p>
<p class="inwebparagraph"><a id="SP9"></a><b>&#167;9. </b>Once loaded, wherever they came from, we sometimes need to look up a
module by name.
</p>
<pre class="display">
<span class="reserved">module</span><span class="plain"> *</span><span class="functiontext">Modules::find_loaded_by_name</span><span class="plain">(</span><span class="reserved">text_file_position</span><span class="plain"> *</span><span class="identifier">tfp</span><span class="plain">, </span><span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">name</span><span class="plain">) {</span>
<span class="reserved">module</span><span class="plain"> *</span><span class="identifier">M</span><span class="plain">;</span>
<span class="identifier">LOOP_OVER</span><span class="plain">(</span><span class="identifier">M</span><span class="plain">, </span><span class="reserved">module</span><span class="plain">)</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Str::eq</span><span class="plain">(</span><span class="identifier">name</span><span class="plain">, </span><span class="identifier">M</span><span class="plain">-</span><span class="element">&gt;module_name</span><span class="plain">))</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">M</span><span class="plain">;</span>
<span class="functiontext">Errors::in_text_file</span><span class="plain">(</span><span class="string">"unknown module name"</span><span class="plain">, </span><span class="identifier">tfp</span><span class="plain">);</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Modules::find_loaded_by_name is used in 6/mkf (<a href="6-mkf.html#SP2_9">&#167;2.9</a>, <a href="6-mkf.html#SP2_11">&#167;2.11</a>).</p>
2019-03-12 23:32:12 +00:00
<hr class="tocbar">
<ul class="toc"><li><a href="2-tr.html">Back to 'The Reader'</a></li><li><a href="2-lc.html">Continue with 'Line Categories'</a></li></ul><hr class="tocbar">
2019-03-17 12:53:52 +00:00
<!--End of weave: 131 lines from a web of 21211-->
2019-02-04 22:26:45 +00:00
</body>
</html>