1
0
Fork 0
mirror of https://github.com/ganelson/inform.git synced 2024-06-06 02:18:09 +03:00

Tidied up the inter tool

This commit is contained in:
Graham Nelson 2020-03-29 00:22:31 +00:00
parent dbd514292f
commit 5a5ba70c21
14 changed files with 708 additions and 640 deletions

View file

@ -1,6 +1,6 @@
# Inform 7
v10.1.0-alpha.1+6Q29 'Krypton' (28 March 2020)
v10.1.0-alpha.1+6Q30 'Krypton' (29 March 2020)
## About Inform 7

View file

@ -1,3 +1,3 @@
Prerelease: alpha.1
Build Date: 28 March 2020
Build Number: 6Q29
Build Date: 29 March 2020
Build Number: 6Q30

View file

@ -59,9 +59,26 @@
<!--Weave of '1/mn' generated by 7-->
<ul class="crumbs"><li><a href="../webs.html">Source</a></li><li><a href="../compiler.html">Compiler Tools</a></li><li><a href="index.html">inbuild</a></li><li><a href="index.html#1">Chapter 1: Outside of inform7</a></li><li><b>Main</b></li></ul><p class="purpose">A command-line interface for Inbuild functions which are not part of the normal operation of the Inform compiler.</p>
<ul class="toc"><li><a href="#SP1">&#167;1. Main routine</a></li><li><a href="#SP1_6">&#167;1.6. Target list</a></li><li><a href="#SP1_7">&#167;1.7. Command line</a></li><li><a href="#SP4">&#167;4. Interface to Words module</a></li><li><a href="#SP5">&#167;5. Interface to Syntax module</a></li></ul><hr class="tocbar">
<ul class="toc"><li><a href="#SP1">&#167;1. Settings variables</a></li><li><a href="#SP2">&#167;2. Main routine</a></li><li><a href="#SP2_6">&#167;2.6. Target list</a></li><li><a href="#SP2_7">&#167;2.7. Command line</a></li><li><a href="#SP5">&#167;5. Interface to Words module</a></li><li><a href="#SP6">&#167;6. Interface to Syntax module</a></li></ul><hr class="tocbar">
<p class="inwebparagraph"><a id="SP1"></a><b>&#167;1. Main routine. </b>When Inbuild is called at the command line, it begins at <code class="display"><span class="extract">main</span></code>, like all C
<p class="inwebparagraph"><a id="SP1"></a><b>&#167;1. Settings variables. </b>The following will be set at the command line.
</p>
<pre class="display">
<span class="reserved">pathname</span><span class="plain"> *</span><span class="identifier">path_to_inbuild</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">inbuild_task</span><span class="plain"> = </span><span class="constant">INSPECT_TTASK</span><span class="plain">;</span>
<span class="reserved">pathname</span><span class="plain"> *</span><span class="identifier">path_to_tools</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">dry_run_mode</span><span class="plain"> = </span><span class="constant">FALSE</span><span class="plain">, </span><span class="identifier">build_trace_mode</span><span class="plain"> = </span><span class="constant">FALSE</span><span class="plain">;</span>
<span class="reserved">inbuild_nest</span><span class="plain"> *</span><span class="identifier">destination_nest</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">filter_text</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">unit_test</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP2"></a><b>&#167;2. Main routine. </b>When Inbuild is called at the command line, it begins at <code class="display"><span class="extract">main</span></code>, like all C
programs.
</p>
@ -74,21 +91,13 @@ on; then to carry out that work, and then shut down again.
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">inbuild_task</span><span class="plain"> = </span><span class="constant">INSPECT_TTASK</span><span class="plain">;</span>
<span class="reserved">pathname</span><span class="plain"> *</span><span class="identifier">path_to_inbuild</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">pathname</span><span class="plain"> *</span><span class="identifier">path_to_tools</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">dry_run_mode</span><span class="plain"> = </span><span class="constant">FALSE</span><span class="plain">, </span><span class="identifier">build_trace_mode</span><span class="plain"> = </span><span class="constant">FALSE</span><span class="plain">;</span>
<span class="reserved">inbuild_nest</span><span class="plain"> *</span><span class="identifier">destination_nest</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">filter_text</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">unit_test</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">main</span><span class="plain">(</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">argc</span><span class="plain">, </span><span class="reserved">char</span><span class="plain"> **</span><span class="identifier">argv</span><span class="plain">) {</span>
&lt;<span class="cwebmacro">Start up the modules</span> <span class="cwebmacronumber">1.1</span>&gt;<span class="plain">;</span>
&lt;<span class="cwebmacro">Read the command line</span> <span class="cwebmacronumber">1.7</span>&gt;<span class="plain">;</span>
&lt;<span class="cwebmacro">Start up the modules</span> <span class="cwebmacronumber">2.1</span>&gt;<span class="plain">;</span>
&lt;<span class="cwebmacro">Read the command line</span> <span class="cwebmacronumber">2.7</span>&gt;<span class="plain">;</span>
<span class="functiontext">CommandLine::play_back_log</span><span class="plain">();</span>
&lt;<span class="cwebmacro">Complete the list of targets</span> <span class="cwebmacronumber">1.2</span>&gt;<span class="plain">;</span>
&lt;<span class="cwebmacro">Act on the targets</span> <span class="cwebmacronumber">1.3</span>&gt;<span class="plain">;</span>
&lt;<span class="cwebmacro">Shut down the modules</span> <span class="cwebmacronumber">1.4</span>&gt;<span class="plain">;</span>
&lt;<span class="cwebmacro">Complete the list of targets</span> <span class="cwebmacronumber">2.2</span>&gt;<span class="plain">;</span>
&lt;<span class="cwebmacro">Act on the targets</span> <span class="cwebmacronumber">2.3</span>&gt;<span class="plain">;</span>
&lt;<span class="cwebmacro">Shut down the modules</span> <span class="cwebmacronumber">2.4</span>&gt;<span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Errors::have_occurred</span><span class="plain">()) </span><span class="reserved">return</span><span class="plain"> 1;</span>
<span class="reserved">return</span><span class="plain"> 0;</span>
<span class="plain">}</span>
@ -98,8 +107,8 @@ on; then to carry out that work, and then shut down again.
<p class="endnote">The function main is used in 1/ic (<a href="1-ic.html#SP23">&#167;23</a>), 5/kts (<a href="5-kts.html#SP1">&#167;1</a>), 6/st (<a href="6-st.html#SP1">&#167;1</a>).</p>
<p class="inwebparagraph"><a id="SP1_1"></a><b>&#167;1.1. </b><code class="display">
&lt;<span class="cwebmacrodefn">Start up the modules</span> <span class="cwebmacronumber">1.1</span>&gt; =
<p class="inwebparagraph"><a id="SP2_1"></a><b>&#167;2.1. </b><code class="display">
&lt;<span class="cwebmacrodefn">Start up the modules</span> <span class="cwebmacronumber">2.1</span>&gt; =
</code></p>
@ -114,9 +123,9 @@ on; then to carry out that work, and then shut down again.
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP1">&#167;1</a>.</p>
<p class="endnote">This code is used in <a href="#SP2">&#167;2</a>.</p>
<p class="inwebparagraph"><a id="SP1_2"></a><b>&#167;1.2. </b>Targets can arise in three ways:
<p class="inwebparagraph"><a id="SP2_2"></a><b>&#167;2.2. </b>Targets can arise in three ways:
</p>
<ul class="items"><li>(1) They can be specified at the command line, either as bare names of files
@ -142,7 +151,7 @@ error in this case.
</li></ul>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Complete the list of targets</span> <span class="cwebmacronumber">1.2</span>&gt; =
&lt;<span class="cwebmacrodefn">Complete the list of targets</span> <span class="cwebmacronumber">2.2</span>&gt; =
</code></p>
@ -165,15 +174,15 @@ error in this case.
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP1">&#167;1</a>.</p>
<p class="endnote">This code is used in <a href="#SP2">&#167;2</a>.</p>
<p class="inwebparagraph"><a id="SP1_3"></a><b>&#167;1.3. </b>We make the function call <code class="display"><span class="extract">Inbuild::go_operational</span></code> to signal to <code class="display"><span class="extract">inbuild</span></code>
<p class="inwebparagraph"><a id="SP2_3"></a><b>&#167;2.3. </b>We make the function call <code class="display"><span class="extract">Inbuild::go_operational</span></code> to signal to <code class="display"><span class="extract">inbuild</span></code>
that we want to start work now.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Act on the targets</span> <span class="cwebmacronumber">1.3</span>&gt; =
&lt;<span class="cwebmacrodefn">Act on the targets</span> <span class="cwebmacronumber">2.3</span>&gt; =
</code></p>
@ -192,15 +201,15 @@ that we want to start work now.
<span class="reserved">linked_list</span><span class="plain"> *</span><span class="identifier">L</span><span class="plain"> = </span><span class="functiontext">Main::list_of_targets</span><span class="plain">();</span>
<span class="reserved">inbuild_copy</span><span class="plain"> *</span><span class="identifier">C</span><span class="plain">;</span>
<span class="identifier">LOOP_OVER_LINKED_LIST</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">, </span><span class="reserved">inbuild_copy</span><span class="plain">, </span><span class="identifier">L</span><span class="plain">)</span>
&lt;<span class="cwebmacro">Carry out the required task on the copy C</span> <span class="cwebmacronumber">1.3.2</span>&gt;<span class="plain">;</span>
&lt;<span class="cwebmacro">Carry out the required task on the copy C</span> <span class="cwebmacronumber">2.3.2</span>&gt;<span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP1">&#167;1</a>.</p>
<p class="endnote">This code is used in <a href="#SP2">&#167;2</a>.</p>
<p class="inwebparagraph"><a id="SP1_3_1"></a><b>&#167;1.3.1. </b>The list of possible tasks is as follows; they basically all correspond to
<p class="inwebparagraph"><a id="SP2_3_1"></a><b>&#167;2.3.1. </b>The list of possible tasks is as follows; they basically all correspond to
utility functions in the <code class="display"><span class="extract">inbuild</span></code> module, which we call.
</p>
@ -219,8 +228,8 @@ utility functions in the <code class="display"><span class="extract">inbuild</sp
<span class="definitionkeyword">enum</span> <span class="constant">COPY_TO_TTASK</span>
<span class="definitionkeyword">enum</span> <span class="constant">SYNC_TO_TTASK</span>
</pre>
<p class="inwebparagraph"><a id="SP1_3_2"></a><b>&#167;1.3.2. </b><code class="display">
&lt;<span class="cwebmacrodefn">Carry out the required task on the copy C</span> <span class="cwebmacronumber">1.3.2</span>&gt; =
<p class="inwebparagraph"><a id="SP2_3_2"></a><b>&#167;2.3.2. </b><code class="display">
&lt;<span class="cwebmacrodefn">Carry out the required task on the copy C</span> <span class="cwebmacronumber">2.3.2</span>&gt; =
</code></p>
@ -249,10 +258,10 @@ utility functions in the <code class="display"><span class="extract">inbuild</sp
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP1_3">&#167;1.3</a>.</p>
<p class="endnote">This code is used in <a href="#SP2_3">&#167;2.3</a>.</p>
<p class="inwebparagraph"><a id="SP1_4"></a><b>&#167;1.4. </b><code class="display">
&lt;<span class="cwebmacrodefn">Shut down the modules</span> <span class="cwebmacronumber">1.4</span>&gt; =
<p class="inwebparagraph"><a id="SP2_4"></a><b>&#167;2.4. </b><code class="display">
&lt;<span class="cwebmacrodefn">Shut down the modules</span> <span class="cwebmacronumber">2.4</span>&gt; =
</code></p>
@ -267,9 +276,9 @@ utility functions in the <code class="display"><span class="extract">inbuild</sp
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP1">&#167;1</a>.</p>
<p class="endnote">This code is used in <a href="#SP2">&#167;2</a>.</p>
<p class="inwebparagraph"><a id="SP1_5"></a><b>&#167;1.5. </b>Preform is the crowning jewel of the <code class="display"><span class="extract">words</span></code> module, and parses excerpts of
<p class="inwebparagraph"><a id="SP2_5"></a><b>&#167;2.5. </b>Preform is the crowning jewel of the <code class="display"><span class="extract">words</span></code> module, and parses excerpts of
natural-language text against a "grammar". The <code class="display"><span class="extract">inform7</span></code> executable makes very
heavy-duty use of Preform, but we use a much coarser grammar, which simply
breaks down source text into sentences, headings and so on. That grammar is
@ -291,9 +300,9 @@ for use.
<p class="inwebparagraph"></p>
<p class="endnote">The function Main::load_preform is used in <a href="#SP1_2">&#167;1.2</a>.</p>
<p class="endnote">The function Main::load_preform is used in <a href="#SP2_2">&#167;2.2</a>.</p>
<p class="inwebparagraph"><a id="SP1_6"></a><b>&#167;1.6. Target list. </b>This where we keep the list of targets, in which no copy occurs more than
<p class="inwebparagraph"><a id="SP2_6"></a><b>&#167;2.6. Target list. </b>This where we keep the list of targets, in which no copy occurs more than
once. The following code runs quadratically in the number of targets, but for
Inbuild this number is never likely to be more than about 100 at a time.
</p>
@ -357,17 +366,17 @@ Inbuild this number is never likely to be more than about 100 at a time.
<p class="inwebparagraph"></p>
<p class="endnote">The function Main::add_target is used in <a href="#SP1_2">&#167;1.2</a>.</p>
<p class="endnote">The function Main::add_target is used in <a href="#SP2_2">&#167;2.2</a>.</p>
<p class="endnote">The function Main::list_of_targets is used in <a href="#SP1_2">&#167;1.2</a>, <a href="#SP1_3">&#167;1.3</a>.</p>
<p class="endnote">The function Main::list_of_targets is used in <a href="#SP2_2">&#167;2.2</a>, <a href="#SP2_3">&#167;2.3</a>.</p>
<p class="endnote">The function Main::add_search_results_as_targets is used in <a href="#SP1_2">&#167;1.2</a>.</p>
<p class="endnote">The function Main::add_search_results_as_targets is used in <a href="#SP2_2">&#167;2.2</a>.</p>
<p class="endnote">The function Main::add_directory_contents_targets is used in <a href="#SP2">&#167;2</a>.</p>
<p class="endnote">The function Main::add_directory_contents_targets is used in <a href="#SP3">&#167;3</a>.</p>
<p class="endnote">The function Main::add_file_or_path_as_target is used in <a href="#SP3">&#167;3</a>.</p>
<p class="endnote">The function Main::add_file_or_path_as_target is used in <a href="#SP4">&#167;4</a>.</p>
<p class="inwebparagraph"><a id="SP1_7"></a><b>&#167;1.7. Command line. </b>Note the call below to <code class="display"><span class="extract">Inbuild::declare_options</span></code>, which adds a whole lot of
<p class="inwebparagraph"><a id="SP2_7"></a><b>&#167;2.7. Command line. </b>Note the call below to <code class="display"><span class="extract">Inbuild::declare_options</span></code>, which adds a whole lot of
other options to the selection defined here.
</p>
@ -395,7 +404,7 @@ other options to the selection defined here.
</pre>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Read the command line</span> <span class="cwebmacronumber">1.7</span>&gt; =
&lt;<span class="cwebmacrodefn">Read the command line</span> <span class="cwebmacronumber">2.7</span>&gt; =
</code></p>
@ -452,9 +461,9 @@ other options to the selection defined here.
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP1">&#167;1</a>.</p>
<p class="endnote">This code is used in <a href="#SP2">&#167;2</a>.</p>
<p class="inwebparagraph"><a id="SP2"></a><b>&#167;2. </b>Here we handle those options not handled by the <code class="display"><span class="extract">inbuild</span></code> module.
<p class="inwebparagraph"><a id="SP3"></a><b>&#167;3. </b>Here we handle those options not handled by the <code class="display"><span class="extract">inbuild</span></code> module.
</p>
@ -494,9 +503,9 @@ other options to the selection defined here.
<p class="inwebparagraph"></p>
<p class="endnote">The function Main::option is used in <a href="#SP1_7">&#167;1.7</a>.</p>
<p class="endnote">The function Main::option is used in <a href="#SP2_7">&#167;2.7</a>.</p>
<p class="inwebparagraph"><a id="SP3"></a><b>&#167;3. </b>This is called for a command-line argument which doesn't appear as
<p class="inwebparagraph"><a id="SP4"></a><b>&#167;4. </b>This is called for a command-line argument which doesn't appear as
subordinate to any switch; we take it as the name of a copy.
</p>
@ -509,9 +518,9 @@ subordinate to any switch; we take it as the name of a copy.
<p class="inwebparagraph"></p>
<p class="endnote">The function Main::bareword is used in <a href="#SP1_7">&#167;1.7</a>.</p>
<p class="endnote">The function Main::bareword is used in <a href="#SP2_7">&#167;2.7</a>.</p>
<p class="inwebparagraph"><a id="SP4"></a><b>&#167;4. Interface to Words module. </b>We use the mighty Preform natural-language parser only a little when
<p class="inwebparagraph"><a id="SP5"></a><b>&#167;5. Interface to Words module. </b>We use the mighty Preform natural-language parser only a little when
Inbuild runs on its own, but it needs to be told what C type to use when
identifying natural languages.
</p>
@ -520,7 +529,7 @@ identifying natural languages.
<pre class="definitions">
<span class="definitionkeyword">define</span> <span class="constant">PREFORM_LANGUAGE_TYPE</span><span class="plain"> </span><span class="reserved">struct</span><span class="plain"> </span><span class="reserved">inform_language</span>
</pre>
<p class="inwebparagraph"><a id="SP5"></a><b>&#167;5. Interface to Syntax module. </b>Again, we make a fairly light use of <code class="display"><span class="extract">syntax</span></code> when Inbuild runs alone.
<p class="inwebparagraph"><a id="SP6"></a><b>&#167;6. Interface to Syntax module. </b>Again, we make a fairly light use of <code class="display"><span class="extract">syntax</span></code> when Inbuild runs alone.
</p>

View file

@ -57,49 +57,214 @@
<main role="main">
<!--Weave of '1/mn' generated by 7-->
<ul class="crumbs"><li><a href="../webs.html">Source</a></li><li><a href="../compiler.html">Compiler Tools</a></li><li><a href="index.html">inter</a></li><li><a href="index.html#1">Chapter 1: Outside of inform7</a></li><li><b>Main</b></li></ul><p class="purpose">The top level, which decides what is to be done and then carries this plan out.</p>
<ul class="crumbs"><li><a href="../webs.html">Source</a></li><li><a href="../compiler.html">Compiler Tools</a></li><li><a href="index.html">inter</a></li><li><a href="index.html#1">Chapter 1: Outside of inform7</a></li><li><b>Main</b></li></ul><p class="purpose">A command-line interface for Inter functions which are not part of the normal operation of the Inform compiler.</p>
<ul class="toc"><li><a href="#SP1">&#167;1. Main routine</a></li></ul><hr class="tocbar">
<ul class="toc"><li><a href="#SP1">&#167;1. Settings variables</a></li><li><a href="#SP2">&#167;2. Main routine</a></li><li><a href="#SP2_7">&#167;2.7. Command line</a></li></ul><hr class="tocbar">
<p class="inwebparagraph"><a id="SP1"></a><b>&#167;1. Main routine. </b></p>
<p class="inwebparagraph"><a id="SP1"></a><b>&#167;1. Settings variables. </b>The following will be set at the command line.
</p>
<pre class="display">
<span class="reserved">pathname</span><span class="plain"> *</span><span class="identifier">path_to_inter</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">pathname</span><span class="plain"> *</span><span class="identifier">kit_to_assimilate</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">pathname</span><span class="plain"> *</span><span class="identifier">domain_path</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">linked_list</span><span class="plain"> *</span><span class="identifier">inter_file_list</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">; </span> <span class="comment">of <code class="display"><span class="extract">filename</span></code></span>
<span class="reserved">filename</span><span class="plain"> *</span><span class="identifier">output_textually</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">filename</span><span class="plain"> *</span><span class="identifier">output_binarily</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">dictionary</span><span class="plain"> *</span><span class="identifier">pipeline_vars</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">filename</span><span class="plain"> *</span><span class="identifier">pipeline_as_file</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">pipeline_as_text</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Main::add_pipeline_variable</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">text_stream</span><span class="plain"> *</span><span class="identifier">value</span><span class="plain">) {</span>
<span class="functiontext">Str::copy</span><span class="plain">(</span><span class="functiontext">Dictionaries::create_text</span><span class="plain">(</span><span class="identifier">pipeline_vars</span><span class="plain">, </span><span class="identifier">name</span><span class="plain">), </span><span class="identifier">value</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Main::add_pipeline_variable_from_filename</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">filename</span><span class="plain"> *</span><span class="identifier">F</span><span class="plain">) {</span>
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">fullname</span><span class="plain">);</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">fullname</span><span class="plain">, </span><span class="string">"%f"</span><span class="plain">, </span><span class="identifier">F</span><span class="plain">);</span>
<span class="functiontext">Main::add_pipeline_variable</span><span class="plain">(</span><span class="identifier">name</span><span class="plain">, </span><span class="identifier">fullname</span><span class="plain">);</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">fullname</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Main::add_pipeline_variable is used in <a href="#SP2_3">&#167;2.3</a>, <a href="#SP3_1">&#167;3.1</a>.</p>
<p class="endnote">The function Main::add_pipeline_variable_from_filename is used in <a href="#SP2_3">&#167;2.3</a>.</p>
<p class="inwebparagraph"><a id="SP2"></a><b>&#167;2. Main routine. </b>When Inter is called at the command line, it begins at <code class="display"><span class="extract">main</span></code>, like all C
programs.
</p>
<p class="inwebparagraph">Inter can do three different things: assimilate a kit, run a pipeline of
code generation stages, and verify/transcode files of Inter code. In fact,
though, that's really only two different things, because assimilation is
also done with a pipeline.
</p>
<pre class="display">
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">main</span><span class="plain">(</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">argc</span><span class="plain">, </span><span class="reserved">char</span><span class="plain"> **</span><span class="identifier">argv</span><span class="plain">) {</span>
&lt;<span class="cwebmacro">Start up the modules</span> <span class="cwebmacronumber">2.1</span>&gt;<span class="plain">;</span>
&lt;<span class="cwebmacro">Begin with an empty file list and variables dictionary</span> <span class="cwebmacronumber">2.2</span>&gt;<span class="plain">;</span>
&lt;<span class="cwebmacro">Read the command line</span> <span class="cwebmacronumber">2.7</span>&gt;<span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">kit_to_assimilate</span><span class="plain">) </span>&lt;<span class="cwebmacro">Set up a pipeline for assimilation</span> <span class="cwebmacronumber">2.3</span>&gt;<span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">pipeline_as_file</span><span class="plain">) || (</span><span class="identifier">pipeline_as_text</span><span class="plain">))</span>
&lt;<span class="cwebmacro">Run the pipeline</span> <span class="cwebmacronumber">2.4</span>&gt;
<span class="reserved">else</span>
&lt;<span class="cwebmacro">Read the list of inter files, and perhaps transcode them</span> <span class="cwebmacronumber">2.5</span>&gt;<span class="plain">;</span>
&lt;<span class="cwebmacro">Shut down the modules</span> <span class="cwebmacronumber">2.6</span>&gt;<span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Errors::have_occurred</span><span class="plain">()) </span><span class="reserved">return</span><span class="plain"> 1;</span>
<span class="reserved">return</span><span class="plain"> 0;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function main is used in 2/pck (<a href="2-pck.html#SP3">&#167;3</a>), 2/cnn (<a href="2-cnn.html#SP1">&#167;1</a>), 1/bs (<a href="1-bs.html#SP2">&#167;2</a>), 3/fc (<a href="3-fc.html#SP1">&#167;1</a>).</p>
<p class="inwebparagraph"><a id="SP2_1"></a><b>&#167;2.1. </b><code class="display">
&lt;<span class="cwebmacrodefn">Start up the modules</span> <span class="cwebmacronumber">2.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="functiontext">Foundation::start</span><span class="plain">(); </span> <span class="comment">must be started first</span>
<span class="functiontext">ArchModule::start</span><span class="plain">();</span>
<span class="functiontext">InterModule::start</span><span class="plain">();</span>
<span class="functiontext">BuildingModule::start</span><span class="plain">();</span>
<span class="functiontext">CodegenModule::start</span><span class="plain">();</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP2">&#167;2</a>.</p>
<p class="inwebparagraph"><a id="SP2_2"></a><b>&#167;2.2. </b><code class="display">
&lt;<span class="cwebmacrodefn">Begin with an empty file list and variables dictionary</span> <span class="cwebmacronumber">2.2</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">inter_file_list</span><span class="plain"> = </span><span class="identifier">NEW_LINKED_LIST</span><span class="plain">(</span><span class="reserved">filename</span><span class="plain">);</span>
<span class="identifier">pipeline_vars</span><span class="plain"> = </span><span class="functiontext">CodeGen::Pipeline::basic_dictionary</span><span class="plain">(</span><span class="identifier">I</span><span class="string">"output.i6"</span><span class="plain">);</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP2">&#167;2</a>.</p>
<p class="inwebparagraph"><a id="SP2_3"></a><b>&#167;2.3. </b>This pipeline is supplied built in to the installation of <code class="display"><span class="extract">inter</span></code>. In fact,
it only ever writes the binary form of the code it produces, so only <code class="display"><span class="extract">*out</span></code>
is used. But at times in the past it has been useful to debug with the text
form, which would be written to <code class="display"><span class="extract">*outt</span></code>.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Set up a pipeline for assimilation</span> <span class="cwebmacronumber">2.3</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">inter_architecture</span><span class="plain"> *</span><span class="identifier">A</span><span class="plain"> = </span><span class="functiontext">CodeGen::Architecture::current</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="functiontext">Errors::fatal</span><span class="plain">(</span><span class="string">"no -architecture given"</span><span class="plain">);</span>
<span class="reserved">pathname</span><span class="plain"> *</span><span class="identifier">path_to_pipelines</span><span class="plain"> = </span><span class="functiontext">Pathnames::subfolder</span><span class="plain">(</span><span class="identifier">path_to_inter</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Pipelines"</span><span class="plain">);</span>
<span class="identifier">pipeline_as_file</span><span class="plain"> = </span><span class="functiontext">Filenames::in_folder</span><span class="plain">(</span><span class="identifier">path_to_pipelines</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"assimilate.interpipeline"</span><span class="plain">);</span>
<span class="identifier">pipeline_as_text</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="functiontext">Main::add_pipeline_variable</span><span class="plain">(</span><span class="identifier">I</span><span class="string">"*kit"</span><span class="plain">,</span>
<span class="functiontext">Pathnames::directory_name</span><span class="plain">(</span><span class="identifier">kit_to_assimilate</span><span class="plain">));</span>
<span class="functiontext">Main::add_pipeline_variable_from_filename</span><span class="plain">(</span><span class="identifier">I</span><span class="string">"*out"</span><span class="plain">,</span>
<span class="functiontext">Architectures::canonical_binary</span><span class="plain">(</span><span class="identifier">kit_to_assimilate</span><span class="plain">, </span><span class="identifier">A</span><span class="plain">));</span>
<span class="functiontext">Main::add_pipeline_variable_from_filename</span><span class="plain">(</span><span class="identifier">I</span><span class="string">"*outt"</span><span class="plain">,</span>
<span class="functiontext">Architectures::canonical_textual</span><span class="plain">(</span><span class="identifier">kit_to_assimilate</span><span class="plain">, </span><span class="identifier">A</span><span class="plain">));</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP2">&#167;2</a>.</p>
<p class="inwebparagraph"><a id="SP2_4"></a><b>&#167;2.4. </b><code class="display">
&lt;<span class="cwebmacrodefn">Run the pipeline</span> <span class="cwebmacronumber">2.4</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">LinkedLists::len</span><span class="plain">(</span><span class="identifier">inter_file_list</span><span class="plain">) &gt; 0)</span>
<span class="functiontext">Errors::fatal</span><span class="plain">(</span><span class="string">"-pipeline-text and -pipeline-file cannot be combined with inter files"</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">pipeline_as_file</span><span class="plain">) &amp;&amp; (</span><span class="identifier">pipeline_as_text</span><span class="plain">))</span>
<span class="functiontext">Errors::fatal</span><span class="plain">(</span><span class="string">"-pipeline-text and -pipeline-file are mutually exclusive"</span><span class="plain">);</span>
<span class="reserved">linked_list</span><span class="plain"> *</span><span class="identifier">inter_paths</span><span class="plain"> = </span><span class="identifier">NEW_LINKED_LIST</span><span class="plain">(</span><span class="reserved">pathname</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">kit_to_assimilate</span><span class="plain">) </span><span class="identifier">ADD_TO_LINKED_LIST</span><span class="plain">(</span><span class="identifier">kit_to_assimilate</span><span class="plain">, </span><span class="reserved">pathname</span><span class="plain">, </span><span class="identifier">inter_paths</span><span class="plain">);</span>
<span class="reserved">codegen_pipeline</span><span class="plain"> *</span><span class="identifier">SS</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">pipeline_as_file</span><span class="plain">)</span>
<span class="identifier">SS</span><span class="plain"> = </span><span class="functiontext">CodeGen::Pipeline::parse_from_file</span><span class="plain">(</span><span class="identifier">pipeline_as_file</span><span class="plain">, </span><span class="identifier">pipeline_vars</span><span class="plain">);</span>
<span class="reserved">else</span>
<span class="identifier">SS</span><span class="plain"> = </span><span class="functiontext">CodeGen::Pipeline::parse</span><span class="plain">(</span><span class="identifier">pipeline_as_text</span><span class="plain">, </span><span class="identifier">pipeline_vars</span><span class="plain">);</span>
<span class="reserved">linked_list</span><span class="plain"> *</span><span class="identifier">requirements_list</span><span class="plain"> = </span><span class="identifier">NEW_LINKED_LIST</span><span class="plain">(</span><span class="identifier">inter_library</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">SS</span><span class="plain">) </span><span class="functiontext">CodeGen::Pipeline::run</span><span class="plain">(</span><span class="identifier">domain_path</span><span class="plain">, </span><span class="identifier">SS</span><span class="plain">, </span><span class="identifier">inter_paths</span><span class="plain">, </span><span class="identifier">requirements_list</span><span class="plain">);</span>
<span class="reserved">else</span><span class="plain"> </span><span class="functiontext">Errors::fatal</span><span class="plain">(</span><span class="string">"pipeline could not be parsed"</span><span class="plain">);</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP2">&#167;2</a>.</p>
<p class="inwebparagraph"><a id="SP2_5"></a><b>&#167;2.5. </b><code class="display">
&lt;<span class="cwebmacrodefn">Read the list of inter files, and perhaps transcode them</span> <span class="cwebmacronumber">2.5</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">inter_tree</span><span class="plain"> *</span><span class="identifier">I</span><span class="plain"> = </span><span class="functiontext">Inter::Tree::new</span><span class="plain">();</span>
<span class="reserved">filename</span><span class="plain"> *</span><span class="identifier">F</span><span class="plain">;</span>
<span class="identifier">LOOP_OVER_LINKED_LIST</span><span class="plain">(</span><span class="identifier">F</span><span class="plain">, </span><span class="reserved">filename</span><span class="plain">, </span><span class="identifier">inter_file_list</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Inter::Binary::test_file</span><span class="plain">(</span><span class="identifier">F</span><span class="plain">))</span>
<span class="functiontext">Inter::Binary::read</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">, </span><span class="identifier">F</span><span class="plain">);</span>
<span class="reserved">else</span>
<span class="functiontext">Inter::Textual::read</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">, </span><span class="identifier">F</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">output_textually</span><span class="plain">) {</span>
<span class="reserved">text_stream</span><span class="plain"> </span><span class="identifier">C_struct</span><span class="plain">; </span><span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">OUT</span><span class="plain"> = &amp;</span><span class="identifier">C_struct</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">STREAM_OPEN_TO_FILE</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">output_textually</span><span class="plain">, </span><span class="constant">UTF8_ENC</span><span class="plain">) == </span><span class="constant">FALSE</span><span class="plain">)</span>
<span class="functiontext">Errors::fatal_with_file</span><span class="plain">(</span><span class="string">"unable to open textual inter file for output: %f"</span><span class="plain">,</span>
<span class="identifier">output_textually</span><span class="plain">);</span>
<span class="functiontext">Inter::Textual::write</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">I</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">, 1);</span>
<span class="identifier">STREAM_CLOSE</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">output_binarily</span><span class="plain">) </span><span class="functiontext">Inter::Binary::write</span><span class="plain">(</span><span class="identifier">output_binarily</span><span class="plain">, </span><span class="identifier">I</span><span class="plain">);</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP2">&#167;2</a>.</p>
<p class="inwebparagraph"><a id="SP2_6"></a><b>&#167;2.6. </b><code class="display">
&lt;<span class="cwebmacrodefn">Shut down the modules</span> <span class="cwebmacronumber">2.6</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="functiontext">InterModule::end</span><span class="plain">();</span>
<span class="functiontext">BuildingModule::end</span><span class="plain">();</span>
<span class="functiontext">CodegenModule::end</span><span class="plain">();</span>
<span class="functiontext">ArchModule::end</span><span class="plain">();</span>
<span class="functiontext">Foundation::end</span><span class="plain">(); </span> <span class="comment">must be ended last</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP2">&#167;2</a>.</p>
<p class="inwebparagraph"><a id="SP2_7"></a><b>&#167;2.7. Command line. </b></p>
<pre class="definitions">
<span class="definitionkeyword">define</span> <span class="constant">INTOOL_NAME</span><span class="plain"> </span><span class="string">"inter"</span>
</pre>
<p class="inwebparagraph"><a id="SP2"></a><b>&#167;2. </b>The modules included in <code class="display"><span class="extract">inter</span></code> make use of the Inform 7 module <code class="display"><span class="extract">kinds</span></code>,
but when we are using <code class="display"><span class="extract">inter</span></code> on its own, kinds have no meaning for us.
We are required to create a <code class="display"><span class="extract">kind</span></code> type, in order for <code class="display"><span class="extract">kinds</span></code> to compile;
but no instances of this kind will ever in fact exist. <code class="display"><span class="extract">K_value</span></code> is a
global constant meaning "any kind at all", and that also must exist.
</p>
<pre class="display">
<span class="reserved">typedef</span><span class="plain"> </span><span class="reserved">void</span><span class="plain"> </span><span class="identifier">kind</span><span class="plain">;</span>
<span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">K_value</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP3"></a><b>&#167;3. </b>We need to allocate one additional type of structure in memory, so:
</p>
<pre class="definitions">
<span class="definitionkeyword">enum</span> <span class="constant">inter_file_MT</span>
</pre>
<pre class="display">
<span class="identifier">ALLOCATE_INDIVIDUALLY</span><span class="plain">(</span><span class="reserved">inter_file</span><span class="plain">)</span>
</pre>
<p class="inwebparagraph"></p>
<p class="inwebparagraph"><a id="SP4"></a><b>&#167;4. </b></p>
<pre class="definitions">
<span class="definitionkeyword">enum</span> <span class="constant">TEXTUAL_CLSW</span>
<span class="definitionkeyword">enum</span> <span class="constant">BINARY_CLSW</span>
<span class="definitionkeyword">enum</span> <span class="constant">PIPELINE_CLSW</span>
@ -110,27 +275,12 @@ global constant meaning "any kind at all", and that also must exist.
<span class="definitionkeyword">enum</span> <span class="constant">ASSIMILATE_CLSW</span>
</pre>
<pre class="display">
<span class="reserved">pathname</span><span class="plain"> *</span><span class="identifier">path_to_inter</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">pathname</span><span class="plain"> *</span><span class="identifier">path_to_pipelines</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">pathname</span><span class="plain"> *</span><span class="identifier">kit_path</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">template_action</span><span class="plain"> = -1;</span>
<span class="reserved">pathname</span><span class="plain"> *</span><span class="identifier">domain_path</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">filename</span><span class="plain"> *</span><span class="identifier">output_textually</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">filename</span><span class="plain"> *</span><span class="identifier">output_binarily</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">filename</span><span class="plain"> *</span><span class="identifier">unit_test_file</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">dictionary</span><span class="plain"> *</span><span class="identifier">pipeline_vars</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">filename</span><span class="plain"> *</span><span class="identifier">pipeline_as_file</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">pipeline_as_text</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">linked_list</span><span class="plain"> *</span><span class="identifier">requirements_list</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Read the command line</span> <span class="cwebmacronumber">2.7</span>&gt; =
</code></p>
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">main</span><span class="plain">(</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">argc</span><span class="plain">, </span><span class="reserved">char</span><span class="plain"> **</span><span class="identifier">argv</span><span class="plain">) {</span>
&lt;<span class="cwebmacro">Start up the modules</span> <span class="cwebmacronumber">4.1</span>&gt;<span class="plain">;</span>
<span class="identifier">path_to_inter</span><span class="plain"> = </span><span class="functiontext">Pathnames::installation_path</span><span class="plain">(</span><span class="string">"INTER_PATH"</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"inter"</span><span class="plain">);</span>
<span class="identifier">path_to_pipelines</span><span class="plain"> = </span><span class="functiontext">Pathnames::subfolder</span><span class="plain">(</span><span class="identifier">path_to_inter</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Pipelines"</span><span class="plain">);</span>
<span class="identifier">requirements_list</span><span class="plain"> = </span><span class="identifier">NEW_LINKED_LIST</span><span class="plain">(</span><span class="identifier">inter_library</span><span class="plain">);</span>
<pre class="displaydefn">
<span class="functiontext">CommandLine::declare_heading</span><span class="plain">(</span>
<span class="identifier">L</span><span class="string">"[[Purpose]]\</span><span class="plain">n</span><span class="string">\</span><span class="plain">n</span><span class="string">"</span>
<span class="identifier">L</span><span class="string">"usage: inter file1 file2 ... [options]\</span><span class="plain">n</span><span class="string">"</span><span class="plain">);</span>
@ -152,100 +302,28 @@ global constant meaning "any kind at all", and that also must exist.
<span class="functiontext">CommandLine::declare_switch</span><span class="plain">(</span><span class="constant">ASSIMILATE_CLSW</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"assimilate"</span><span class="plain">, 2,</span>
<span class="identifier">L</span><span class="string">"assimilate (i.e., build) Inter kit X for the current architecture"</span><span class="plain">);</span>
<span class="identifier">pipeline_vars</span><span class="plain"> = </span><span class="functiontext">CodeGen::Pipeline::basic_dictionary</span><span class="plain">(</span><span class="identifier">I</span><span class="string">"output.i6"</span><span class="plain">);</span>
<span class="functiontext">CommandLine::read</span><span class="plain">(</span><span class="identifier">argc</span><span class="plain">, </span><span class="identifier">argv</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">, &amp;</span><span class="functiontext">Main::respond</span><span class="plain">, &amp;</span><span class="functiontext">Main::add_file</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">template_action</span><span class="plain"> == </span><span class="constant">ASSIMILATE_CLSW</span><span class="plain">) {</span>
<span class="reserved">inter_architecture</span><span class="plain"> *</span><span class="identifier">A</span><span class="plain"> = </span><span class="functiontext">CodeGen::Architecture::current</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="functiontext">Errors::fatal</span><span class="plain">(</span><span class="string">"no -architecture given"</span><span class="plain">);</span>
<span class="reserved">filename</span><span class="plain"> *</span><span class="identifier">assim</span><span class="plain"> = </span><span class="functiontext">Architectures::canonical_binary</span><span class="plain">(</span><span class="identifier">kit_path</span><span class="plain">, </span><span class="identifier">A</span><span class="plain">);</span>
<span class="reserved">filename</span><span class="plain"> *</span><span class="identifier">assim_t</span><span class="plain"> = </span><span class="functiontext">Architectures::canonical_textual</span><span class="plain">(</span><span class="identifier">kit_path</span><span class="plain">, </span><span class="identifier">A</span><span class="plain">);</span>
<span class="identifier">pipeline_as_file</span><span class="plain"> = </span><span class="functiontext">Filenames::in_folder</span><span class="plain">(</span><span class="identifier">path_to_pipelines</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"assimilate.interpipeline"</span><span class="plain">);</span>
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">fullname</span><span class="plain">);</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">fullname</span><span class="plain">, </span><span class="string">"%f"</span><span class="plain">, </span><span class="identifier">assim</span><span class="plain">);</span>
<span class="functiontext">Str::copy</span><span class="plain">(</span><span class="functiontext">Dictionaries::create_text</span><span class="plain">(</span><span class="identifier">pipeline_vars</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"*out"</span><span class="plain">), </span><span class="identifier">fullname</span><span class="plain">);</span>
<span class="functiontext">Str::clear</span><span class="plain">(</span><span class="identifier">fullname</span><span class="plain">);</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">fullname</span><span class="plain">, </span><span class="string">"%f"</span><span class="plain">, </span><span class="identifier">assim_t</span><span class="plain">);</span>
<span class="functiontext">Str::copy</span><span class="plain">(</span><span class="functiontext">Dictionaries::create_text</span><span class="plain">(</span><span class="identifier">pipeline_vars</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"*outt"</span><span class="plain">), </span><span class="identifier">fullname</span><span class="plain">);</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">fullname</span><span class="plain">);</span>
<span class="functiontext">Str::copy</span><span class="plain">(</span><span class="functiontext">Dictionaries::create_text</span><span class="plain">(</span><span class="identifier">pipeline_vars</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"*attach"</span><span class="plain">), </span><span class="functiontext">Pathnames::directory_name</span><span class="plain">(</span><span class="identifier">kit_path</span><span class="plain">));</span>
<span class="plain">}</span>
<span class="functiontext">Main::act</span><span class="plain">();</span>
&lt;<span class="cwebmacro">Shut down the modules</span> <span class="cwebmacronumber">4.2</span>&gt;<span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Errors::have_occurred</span><span class="plain">()) </span><span class="reserved">return</span><span class="plain"> 1;</span>
<span class="reserved">return</span><span class="plain"> 0;</span>
<span class="plain">}</span>
<span class="identifier">path_to_inter</span><span class="plain"> = </span><span class="functiontext">Pathnames::installation_path</span><span class="plain">(</span><span class="string">"INTER_PATH"</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"inter"</span><span class="plain">);</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function main is used in 2/pck (<a href="2-pck.html#SP3">&#167;3</a>), 2/cnn (<a href="2-cnn.html#SP1">&#167;1</a>), 1/bs (<a href="1-bs.html#SP2">&#167;2</a>), 3/fc (<a href="3-fc.html#SP1">&#167;1</a>).</p>
<p class="endnote">This code is used in <a href="#SP2">&#167;2</a>.</p>
<p class="inwebparagraph"><a id="SP4_1"></a><b>&#167;4.1. </b><code class="display">
&lt;<span class="cwebmacrodefn">Start up the modules</span> <span class="cwebmacronumber">4.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="functiontext">Foundation::start</span><span class="plain">(); </span> <span class="comment">must be started first</span>
<span class="functiontext">ArchModule::start</span><span class="plain">();</span>
<span class="functiontext">InterModule::start</span><span class="plain">();</span>
<span class="functiontext">BuildingModule::start</span><span class="plain">();</span>
<span class="functiontext">CodegenModule::start</span><span class="plain">();</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP4">&#167;4</a>.</p>
<p class="inwebparagraph"><a id="SP4_2"></a><b>&#167;4.2. </b><code class="display">
&lt;<span class="cwebmacrodefn">Shut down the modules</span> <span class="cwebmacronumber">4.2</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="functiontext">InterModule::end</span><span class="plain">();</span>
<span class="functiontext">BuildingModule::end</span><span class="plain">();</span>
<span class="functiontext">CodegenModule::end</span><span class="plain">();</span>
<span class="functiontext">ArchModule::end</span><span class="plain">();</span>
<span class="functiontext">Foundation::end</span><span class="plain">(); </span> <span class="comment">must be ended last</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP4">&#167;4</a>.</p>
<p class="inwebparagraph"><a id="SP5"></a><b>&#167;5. </b></p>
<p class="inwebparagraph"><a id="SP3"></a><b>&#167;3. </b></p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Main::respond</span><span class="plain">(</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">id</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">val</span><span class="plain">, </span><span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">arg</span><span class="plain">, </span><span class="reserved">void</span><span class="plain"> *</span><span class="identifier">state</span><span class="plain">) {</span>
<span class="reserved">switch</span><span class="plain"> (</span><span class="identifier">id</span><span class="plain">) {</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">TEXTUAL_CLSW</span><span class="plain">: </span><span class="identifier">output_textually</span><span class="plain"> = </span><span class="functiontext">Filenames::from_text</span><span class="plain">(</span><span class="identifier">arg</span><span class="plain">); </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">BINARY_CLSW</span><span class="plain">: </span><span class="identifier">output_binarily</span><span class="plain"> = </span><span class="functiontext">Filenames::from_text</span><span class="plain">(</span><span class="identifier">arg</span><span class="plain">); </span><span class="identifier">pipeline_as_text</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">; </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">BINARY_CLSW</span><span class="plain">: </span><span class="identifier">output_binarily</span><span class="plain"> = </span><span class="functiontext">Filenames::from_text</span><span class="plain">(</span><span class="identifier">arg</span><span class="plain">); </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">PIPELINE_CLSW</span><span class="plain">: </span><span class="identifier">pipeline_as_text</span><span class="plain"> = </span><span class="functiontext">Str::duplicate</span><span class="plain">(</span><span class="identifier">arg</span><span class="plain">); </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">PIPELINE_FILE_CLSW</span><span class="plain">: </span><span class="identifier">pipeline_as_file</span><span class="plain"> = </span><span class="functiontext">Filenames::from_text</span><span class="plain">(</span><span class="identifier">arg</span><span class="plain">); </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">PIPELINE_VARIABLE_CLSW</span><span class="plain">: {</span>
<span class="reserved">match_results</span><span class="plain"> </span><span class="identifier">mr</span><span class="plain"> = </span><span class="functiontext">Regexp::create_mr</span><span class="plain">();</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Regexp::match</span><span class="plain">(&amp;</span><span class="identifier">mr</span><span class="plain">, </span><span class="identifier">arg</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"(%c+)=(%c+)"</span><span class="plain">)) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Str::get_first_char</span><span class="plain">(</span><span class="identifier">arg</span><span class="plain">) != </span><span class="character">'*'</span><span class="plain">) {</span>
<span class="functiontext">Errors::fatal</span><span class="plain">(</span><span class="string">"-variable names must begin with '*'"</span><span class="plain">);</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="functiontext">Str::copy</span><span class="plain">(</span><span class="functiontext">Dictionaries::create_text</span><span class="plain">(</span><span class="identifier">pipeline_vars</span><span class="plain">, </span><span class="identifier">mr</span><span class="element">.exp</span><span class="plain">[0]), </span><span class="identifier">mr</span><span class="element">.exp</span><span class="plain">[1]);</span>
<span class="plain">}</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="functiontext">Errors::fatal</span><span class="plain">(</span><span class="string">"-variable should take the form 'name=value'"</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="functiontext">Regexp::dispose_of</span><span class="plain">(&amp;</span><span class="identifier">mr</span><span class="plain">);</span>
<span class="reserved">break</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">DOMAIN_CLSW</span><span class="plain">: </span><span class="identifier">domain_path</span><span class="plain"> = </span><span class="functiontext">Pathnames::from_text</span><span class="plain">(</span><span class="identifier">arg</span><span class="plain">); </span><span class="identifier">pipeline_as_text</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">; </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">ASSIMILATE_CLSW</span><span class="plain">: </span><span class="identifier">kit_path</span><span class="plain"> = </span><span class="functiontext">Pathnames::from_text</span><span class="plain">(</span><span class="identifier">arg</span><span class="plain">);</span>
<span class="identifier">pipeline_as_text</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">; </span><span class="identifier">template_action</span><span class="plain"> = </span><span class="identifier">id</span><span class="plain">; </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">PIPELINE_VARIABLE_CLSW</span><span class="plain">: </span>&lt;<span class="cwebmacro">Add a pipeline variable to the dictionary</span> <span class="cwebmacronumber">3.1</span>&gt;<span class="plain">; </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">DOMAIN_CLSW</span><span class="plain">: </span><span class="identifier">domain_path</span><span class="plain"> = </span><span class="functiontext">Pathnames::from_text</span><span class="plain">(</span><span class="identifier">arg</span><span class="plain">); </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">ASSIMILATE_CLSW</span><span class="plain">: </span><span class="identifier">kit_to_assimilate</span><span class="plain"> = </span><span class="functiontext">Pathnames::from_text</span><span class="plain">(</span><span class="identifier">arg</span><span class="plain">); </span><span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">ARCHITECTURE_CLSW</span><span class="plain">:</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">CodeGen::Architecture::set</span><span class="plain">(</span><span class="identifier">arg</span><span class="plain">) == </span><span class="constant">FALSE</span><span class="plain">)</span>
<span class="functiontext">Errors::fatal</span><span class="plain">(</span><span class="string">"no such -architecture"</span><span class="plain">);</span>
@ -256,74 +334,61 @@ global constant meaning "any kind at all", and that also must exist.
<p class="inwebparagraph"></p>
<p class="endnote">The function Main::respond is used in <a href="#SP4">&#167;4</a>.</p>
<p class="endnote">The function Main::respond is used in <a href="#SP2_7">&#167;2.7</a>.</p>
<p class="inwebparagraph"><a id="SP6"></a><b>&#167;6. </b></p>
<p class="inwebparagraph"><a id="SP3_1"></a><b>&#167;3.1. </b><code class="display">
&lt;<span class="cwebmacrodefn">Add a pipeline variable to the dictionary</span> <span class="cwebmacronumber">3.1</span>&gt; =
</code></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">inter_file</span><span class="plain"> {</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">filename</span><span class="plain"> *</span><span class="identifier">inter_filename</span><span class="plain">;</span>
<span class="constant">MEMORY_MANAGEMENT</span>
<span class="plain">} </span><span class="reserved">inter_file</span><span class="plain">;</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Main::add_file</span><span class="plain">(</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">id</span><span class="plain">, </span><span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">arg</span><span class="plain">, </span><span class="reserved">void</span><span class="plain"> *</span><span class="identifier">state</span><span class="plain">) {</span>
<span class="reserved">inter_file</span><span class="plain"> *</span><span class="identifier">IF</span><span class="plain"> = </span><span class="identifier">CREATE</span><span class="plain">(</span><span class="reserved">inter_file</span><span class="plain">);</span>
<span class="identifier">IF</span><span class="plain">-</span><span class="element">&gt;inter_filename</span><span class="plain"> = </span><span class="functiontext">Filenames::from_text</span><span class="plain">(</span><span class="identifier">arg</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Main::add_file is used in <a href="#SP4">&#167;4</a>.</p>
<p class="endnote">The structure inter_file is private to this section.</p>
<p class="inwebparagraph"><a id="SP7"></a><b>&#167;7. </b></p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Main::act</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">pipeline_as_file</span><span class="plain">) || (</span><span class="identifier">pipeline_as_text</span><span class="plain">)) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">NUMBER_CREATED</span><span class="plain">(</span><span class="reserved">inter_file</span><span class="plain">) &gt; 0)</span>
<span class="functiontext">Errors::fatal</span><span class="plain">(</span><span class="string">"-pipeline-text and -pipeline-file cannot be combined with inter file parameters"</span><span class="plain">);</span>
<span class="reserved">linked_list</span><span class="plain"> *</span><span class="identifier">inter_paths</span><span class="plain"> = </span><span class="identifier">NEW_LINKED_LIST</span><span class="plain">(</span><span class="reserved">pathname</span><span class="plain">);</span>
<span class="identifier">ADD_TO_LINKED_LIST</span><span class="plain">(</span><span class="identifier">kit_path</span><span class="plain">, </span><span class="reserved">pathname</span><span class="plain">, </span><span class="identifier">inter_paths</span><span class="plain">);</span>
<span class="reserved">codegen_pipeline</span><span class="plain"> *</span><span class="identifier">SS</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">pipeline_as_file</span><span class="plain">) </span><span class="identifier">SS</span><span class="plain"> = </span><span class="functiontext">CodeGen::Pipeline::parse_from_file</span><span class="plain">(</span><span class="identifier">pipeline_as_file</span><span class="plain">, </span><span class="identifier">pipeline_vars</span><span class="plain">);</span>
<span class="reserved">else</span><span class="plain"> </span><span class="identifier">SS</span><span class="plain"> = </span><span class="functiontext">CodeGen::Pipeline::parse</span><span class="plain">(</span><span class="identifier">pipeline_as_text</span><span class="plain">, </span><span class="identifier">pipeline_vars</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">SS</span><span class="plain">) </span><span class="functiontext">CodeGen::Pipeline::run</span><span class="plain">(</span><span class="identifier">domain_path</span><span class="plain">, </span><span class="identifier">SS</span><span class="plain">, </span><span class="identifier">inter_paths</span><span class="plain">, </span><span class="identifier">requirements_list</span><span class="plain">);</span>
<span class="reserved">else</span><span class="plain"> </span><span class="functiontext">Errors::fatal</span><span class="plain">(</span><span class="string">"pipeline could not be parsed"</span><span class="plain">);</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> </span><span class="reserved">if</span><span class="plain"> (</span><span class="identifier">unit_test_file</span><span class="plain">) {</span>
<span class="functiontext">UnitTests::run</span><span class="plain">(</span><span class="identifier">unit_test_file</span><span class="plain">);</span>
<pre class="displaydefn">
<span class="reserved">match_results</span><span class="plain"> </span><span class="identifier">mr</span><span class="plain"> = </span><span class="functiontext">Regexp::create_mr</span><span class="plain">();</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Regexp::match</span><span class="plain">(&amp;</span><span class="identifier">mr</span><span class="plain">, </span><span class="identifier">arg</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"(%c+)=(%c+)"</span><span class="plain">)) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Str::get_first_char</span><span class="plain">(</span><span class="identifier">arg</span><span class="plain">) != </span><span class="character">'*'</span><span class="plain">) {</span>
<span class="functiontext">Errors::fatal</span><span class="plain">(</span><span class="string">"-variable names must begin with '*'"</span><span class="plain">);</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="functiontext">Main::add_pipeline_variable</span><span class="plain">(</span><span class="identifier">mr</span><span class="element">.exp</span><span class="plain">[0], </span><span class="identifier">mr</span><span class="element">.exp</span><span class="plain">[1]);</span>
<span class="plain">}</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="reserved">inter_tree</span><span class="plain"> *</span><span class="identifier">I</span><span class="plain"> = </span><span class="functiontext">Inter::Tree::new</span><span class="plain">();</span>
<span class="reserved">inter_file</span><span class="plain"> *</span><span class="identifier">IF</span><span class="plain">;</span>
<span class="identifier">LOOP_OVER</span><span class="plain">(</span><span class="identifier">IF</span><span class="plain">, </span><span class="reserved">inter_file</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Inter::Binary::test_file</span><span class="plain">(</span><span class="identifier">IF</span><span class="plain">-</span><span class="element">&gt;inter_filename</span><span class="plain">))</span>
<span class="functiontext">Inter::Binary::read</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">, </span><span class="identifier">IF</span><span class="plain">-</span><span class="element">&gt;inter_filename</span><span class="plain">);</span>
<span class="reserved">else</span>
<span class="functiontext">Inter::Textual::read</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">, </span><span class="identifier">IF</span><span class="plain">-</span><span class="element">&gt;inter_filename</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">output_textually</span><span class="plain">) {</span>
<span class="reserved">text_stream</span><span class="plain"> </span><span class="identifier">C_struct</span><span class="plain">; </span><span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">OUT</span><span class="plain"> = &amp;</span><span class="identifier">C_struct</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">STREAM_OPEN_TO_FILE</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">output_textually</span><span class="plain">, </span><span class="constant">UTF8_ENC</span><span class="plain">) == </span><span class="constant">FALSE</span><span class="plain">)</span>
<span class="functiontext">Errors::fatal_with_file</span><span class="plain">(</span><span class="string">"unable to open textual inter file for output: %f"</span><span class="plain">,</span>
<span class="identifier">output_textually</span><span class="plain">);</span>
<span class="functiontext">Inter::Textual::write</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">I</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">, 1);</span>
<span class="identifier">STREAM_CLOSE</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">output_binarily</span><span class="plain">) </span><span class="functiontext">Inter::Binary::write</span><span class="plain">(</span><span class="identifier">output_binarily</span><span class="plain">, </span><span class="identifier">I</span><span class="plain">);</span>
<span class="functiontext">Errors::fatal</span><span class="plain">(</span><span class="string">"-variable should take the form 'name=value'"</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="functiontext">Regexp::dispose_of</span><span class="plain">(&amp;</span><span class="identifier">mr</span><span class="plain">);</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP3">&#167;3</a>.</p>
<p class="inwebparagraph"><a id="SP4"></a><b>&#167;4. </b></p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">Main::add_file</span><span class="plain">(</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">id</span><span class="plain">, </span><span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">arg</span><span class="plain">, </span><span class="reserved">void</span><span class="plain"> *</span><span class="identifier">state</span><span class="plain">) {</span>
<span class="reserved">filename</span><span class="plain"> *</span><span class="identifier">F</span><span class="plain"> = </span><span class="functiontext">Filenames::from_text</span><span class="plain">(</span><span class="identifier">arg</span><span class="plain">);</span>
<span class="identifier">ADD_TO_LINKED_LIST</span><span class="plain">(</span><span class="identifier">F</span><span class="plain">, </span><span class="reserved">filename</span><span class="plain">, </span><span class="identifier">inter_file_list</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function Main::act is used in <a href="#SP4">&#167;4</a>.</p>
<p class="endnote">The function Main::add_file is used in <a href="#SP2_7">&#167;2.7</a>.</p>
<p class="inwebparagraph"><a id="SP5"></a><b>&#167;5. </b>The modules included in <code class="display"><span class="extract">inter</span></code> make use of the Inform 7 module <code class="display"><span class="extract">kinds</span></code>,
but when we are using <code class="display"><span class="extract">inter</span></code> on its own, kinds have no meaning for us.
We are required to create a <code class="display"><span class="extract">kind</span></code> type, in order for <code class="display"><span class="extract">kinds</span></code> to compile;
but no instances of this kind will ever in fact exist. <code class="display"><span class="extract">K_value</span></code> is a
global constant meaning "any kind at all", and that also must exist.
</p>
<pre class="display">
<span class="reserved">typedef</span><span class="plain"> </span><span class="reserved">void</span><span class="plain"> </span><span class="identifier">kind</span><span class="plain">;</span>
<span class="identifier">kind</span><span class="plain"> *</span><span class="identifier">K_value</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
</pre>
<p class="inwebparagraph"></p>
<hr class="tocbar">
<ul class="toc"><li><i>(This section begins Chapter 1: Outside of inform7.)</i></li><li><a href="1-ut.html">Continue with 'Unit Tests'</a></li></ul><hr class="tocbar">
<!--End of weave-->
</main>
</body>

View file

@ -1,165 +0,0 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>1/mn</title>
<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="../inweb.css" rel="stylesheet" rev="stylesheet" type="text/css">
</head>
<body>
<nav role="navigation">
<h1><a href="../webs.html">Sources</a></h1>
<ul>
<li><a href="../compiler.html"><b>compiler tools</b></a></li>
<li><a href="../other.html">other tools</a></li>
<li><a href="../extensions.html">extensions and kits</a></li>
<li><a href="../units.html">unit test tools</a></li>
</ul>
<h2>Compiler Webs</h2>
<ul>
<li><a href="../inbuild/index.html">inbuild</a></li>
<li><a href="../inform7/index.html">inform7</a></li>
<li><a href="../inter/index.html">inter</a></li>
</ul>
<h2>Inbuild Modules</h2>
<ul>
<li><a href="../inbuild-module/index.html">inbuild</a></li>
<li><a href="../arch-module/index.html">arch</a></li>
<li><a href="../words-module/index.html">words</a></li>
<li><a href="../syntax-module/index.html">syntax</a></li>
<li><a href="../html-module/index.html">html</a></li>
</ul>
<h2>Inform7 Modules</h2>
<ul>
<li><a href="../core-module/index.html">core</a></li>
<li><a href="../problems-module/index.html">problems</a></li>
<li><a href="../inflections-module/index.html">inflections</a></li>
<li><a href="../linguistics-module/index.html">linguistics</a></li>
<li><a href="../kinds-module/index.html">kinds</a></li>
<li><a href="../if-module/index.html">if</a></li>
<li><a href="../multimedia-module/index.html">multimedia</a></li>
<li><a href="../index-module/index.html">index</a></li>
</ul>
<h2>Inter Modules</h2>
<ul>
<li><a href="../inter-module/index.html">inter</a></li>
<li><a href="../building-module/index.html">building</a></li>
<li><a href="../codegen-module/index.html">codegen</a></li>
</ul>
<h2>Foundation</h2>
<ul>
<li><a href="../../../inweb/docs/foundation-module/index.html">foundation</a></li>
</ul>
</nav>
<main role="main">
<!--Weave of '1/ut' generated by 7-->
<ul class="crumbs"><li><a href="../webs.html">Source</a></li><li><a href="../compiler.html">Compiler Tools</a></li><li><a href="index.html">inter</a></li><li><a href="index.html#1">Chapter 1: Outside of inform7</a></li><li><b>Unit Tests</b></li></ul><p class="purpose">Scaffolding code to run unit tests not otherwise represented as inter stages.</p>
<p class="inwebparagraph"><a id="SP1"></a><b>&#167;1. </b></p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">UnitTests::run</span><span class="plain">(</span><span class="reserved">filename</span><span class="plain"> *</span><span class="identifier">F</span><span class="plain">) {</span>
<span class="reserved">inter_tree</span><span class="plain"> *</span><span class="identifier">dummy</span><span class="plain"> = </span><span class="functiontext">Inter::Tree::new</span><span class="plain">();</span>
<span class="reserved">inter_bookmark</span><span class="plain"> </span><span class="identifier">IBM</span><span class="plain"> = </span><span class="functiontext">Inter::Bookmarks::at_start_of_this_repository</span><span class="plain">(</span><span class="identifier">dummy</span><span class="plain">);</span>
<span class="functiontext">Primitives::emit</span><span class="plain">(</span><span class="identifier">dummy</span><span class="plain">, &amp;</span><span class="identifier">IBM</span><span class="plain">);</span>
<span class="functiontext">Streams::enable_debugging</span><span class="plain">(</span><span class="constant">STDOUT</span><span class="plain">);</span>
<span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">FORMER_DL</span><span class="plain"> = </span><span class="identifier">DL</span><span class="plain">;</span>
<span class="identifier">DL</span><span class="plain"> = </span><span class="constant">STDOUT</span><span class="plain">;</span>
<span class="reserved">inter_unit_test</span><span class="plain"> </span><span class="identifier">iut</span><span class="plain">;</span>
<span class="identifier">iut</span><span class="element">.to_perform</span><span class="plain"> = </span><span class="constant">NO_IUT</span><span class="plain">;</span>
<span class="identifier">iut</span><span class="element">.test_input</span><span class="plain"> = </span><span class="functiontext">Str::new</span><span class="plain">();</span>
<span class="functiontext">TextFiles::read</span><span class="plain">(</span><span class="identifier">F</span><span class="plain">, </span><span class="constant">FALSE</span><span class="plain">, </span><span class="string">"unable to read tests file"</span><span class="plain">, </span><span class="constant">TRUE</span><span class="plain">,</span>
<span class="plain">&amp;</span><span class="functiontext">UnitTests::test_harvester</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">, &amp;</span><span class="identifier">iut</span><span class="plain">);</span>
<span class="functiontext">Streams::disable_debugging</span><span class="plain">(</span><span class="constant">STDOUT</span><span class="plain">);</span>
<span class="identifier">DL</span><span class="plain"> = </span><span class="identifier">FORMER_DL</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function UnitTests::run is used in 1/mn (<a href="1-mn.html#SP7">&#167;7</a>).</p>
<p class="inwebparagraph"><a id="SP2"></a><b>&#167;2. </b></p>
<pre class="definitions">
<span class="definitionkeyword">enum</span> <span class="constant">NO_IUT</span><span class="definitionkeyword"> from </span><span class="constant">0</span>
<span class="definitionkeyword">enum</span> <span class="constant">SCHEMA_IUT</span>
<span class="definitionkeyword">enum</span> <span class="constant">SCHEMA_WORKINGS_IUT</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">inter_unit_test</span><span class="plain"> {</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">to_perform</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">test_input</span><span class="plain">;</span>
<span class="plain">} </span><span class="reserved">inter_unit_test</span><span class="plain">;</span>
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">UnitTests::test_harvester</span><span class="plain">(</span><span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">text</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">void</span><span class="plain"> *</span><span class="identifier">v_iut</span><span class="plain">) {</span>
<span class="reserved">inter_unit_test</span><span class="plain"> *</span><span class="identifier">iut</span><span class="plain"> = (</span><span class="reserved">inter_unit_test</span><span class="plain"> *) </span><span class="identifier">v_iut</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">text</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"schema"</span><span class="plain">)) {</span>
<span class="identifier">iut</span><span class="plain">-</span><span class="element">&gt;to_perform</span><span class="plain"> = </span><span class="constant">SCHEMA_IUT</span><span class="plain">;</span>
<span class="functiontext">Str::clear</span><span class="plain">(</span><span class="identifier">iut</span><span class="plain">-</span><span class="element">&gt;test_input</span><span class="plain">);</span>
<span class="plain">} </span><span class="reserved">else</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">text</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"schema-workings"</span><span class="plain">)) {</span>
<span class="identifier">iut</span><span class="plain">-</span><span class="element">&gt;to_perform</span><span class="plain"> = </span><span class="constant">SCHEMA_WORKINGS_IUT</span><span class="plain">;</span>
<span class="functiontext">Str::clear</span><span class="plain">(</span><span class="identifier">iut</span><span class="plain">-</span><span class="element">&gt;test_input</span><span class="plain">);</span>
<span class="plain">} </span><span class="reserved">else</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">text</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"end"</span><span class="plain">)) {</span>
<span class="reserved">switch</span><span class="plain"> (</span><span class="identifier">iut</span><span class="plain">-</span><span class="element">&gt;to_perform</span><span class="plain">) {</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">SCHEMA_WORKINGS_IUT</span><span class="plain">:</span>
<span class="functiontext">Log::set_aspect</span><span class="plain">(</span><span class="constant">SCHEMA_COMPILATION_DETAILS_DA</span><span class="plain">, </span><span class="constant">TRUE</span><span class="plain">);</span>
&lt;<span class="cwebmacro">Perform the schema test</span> <span class="cwebmacronumber">2.1</span>&gt;<span class="plain">;</span>
<span class="functiontext">Log::set_aspect</span><span class="plain">(</span><span class="constant">SCHEMA_COMPILATION_DETAILS_DA</span><span class="plain">, </span><span class="constant">FALSE</span><span class="plain">);</span>
<span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">case</span><span class="plain"> </span><span class="constant">SCHEMA_IUT</span><span class="plain">:</span>
&lt;<span class="cwebmacro">Perform the schema test</span> <span class="cwebmacronumber">2.1</span>&gt;<span class="plain">;</span>
<span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">default</span><span class="plain">: </span><span class="functiontext">Errors::in_text_file</span><span class="plain">(</span><span class="string">"unimplemented test"</span><span class="plain">, </span><span class="identifier">tfp</span><span class="plain">); </span><span class="reserved">break</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="identifier">iut</span><span class="plain">-</span><span class="element">&gt;to_perform</span><span class="plain"> = </span><span class="constant">NO_IUT</span><span class="plain">;</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">iut</span><span class="plain">-</span><span class="element">&gt;to_perform</span><span class="plain"> == </span><span class="constant">NO_IUT</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Str::len</span><span class="plain">(</span><span class="identifier">text</span><span class="plain">) == 0) </span><span class="reserved">return</span><span class="plain">;</span>
<span class="functiontext">Errors::in_text_file</span><span class="plain">(</span><span class="string">"content outside of test"</span><span class="plain">, </span><span class="identifier">tfp</span><span class="plain">);</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">iut</span><span class="plain">-</span><span class="element">&gt;test_input</span><span class="plain">, </span><span class="string">"%S\</span><span class="plain">n</span><span class="string">"</span><span class="plain">, </span><span class="identifier">text</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function UnitTests::test_harvester is used in <a href="#SP1">&#167;1</a>.</p>
<p class="endnote">The structure inter_unit_test is private to this section.</p>
<p class="inwebparagraph"><a id="SP2_1"></a><b>&#167;2.1. </b><code class="display">
&lt;<span class="cwebmacrodefn">Perform the schema test</span> <span class="cwebmacronumber">2.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="identifier">LOG</span><span class="plain">(</span><span class="string">"Test: parse schema from:\</span><span class="plain">n</span><span class="string">%S\</span><span class="plain">n</span><span class="string">"</span><span class="plain">, </span><span class="identifier">iut</span><span class="plain">-</span><span class="element">&gt;test_input</span><span class="plain">);</span>
<span class="functiontext">Str::trim_white_space</span><span class="plain">(</span><span class="identifier">iut</span><span class="plain">-</span><span class="element">&gt;test_input</span><span class="plain">);</span>
<span class="reserved">inter_schema</span><span class="plain"> *</span><span class="identifier">sch</span><span class="plain"> = </span><span class="functiontext">InterSchemas::from_text</span><span class="plain">(</span><span class="identifier">iut</span><span class="plain">-</span><span class="element">&gt;test_input</span><span class="plain">, </span><span class="constant">FALSE</span><span class="plain">, 0, </span><span class="identifier">NULL</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">sch</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">LOG</span><span class="plain">(</span><span class="string">"&lt;null schema&gt;\</span><span class="plain">n</span><span class="string">"</span><span class="plain">);</span>
<span class="reserved">else</span><span class="plain"> </span><span class="reserved">if</span><span class="plain"> (</span><span class="identifier">sch</span><span class="plain">-</span><span class="element">&gt;node_tree</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">LOG</span><span class="plain">(</span><span class="string">"&lt;nodeless scheme\</span><span class="plain">n</span><span class="string">"</span><span class="plain">);</span>
<span class="reserved">else</span><span class="plain"> </span><span class="functiontext">InterSchemas::log</span><span class="plain">(</span><span class="identifier">DL</span><span class="plain">, </span><span class="identifier">sch</span><span class="plain">);</span>
<span class="identifier">LOG</span><span class="plain">(</span><span class="string">"=========\</span><span class="plain">n</span><span class="string">"</span><span class="plain">);</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP2">&#167;2</a> (twice).</p>
<hr class="tocbar">
<ul class="toc"><li><a href="1-mn.html">Back to 'Main'</a></li><li><i>(This section ends Chapter 1: Outside of inform7.)</i></li></ul><hr class="tocbar">
<!--End of weave-->
</main>
</body>
</html>

View file

@ -106,11 +106,7 @@
<ul class="sectionlist">
<li>
<p><a href="1-mn.html"><spon class="sectiontitle">Main</span></a> -
<span class="purpose">The top level, which decides what is to be done and then carries this plan out.</span></p>
</li>
<li>
<p><a href="1-ut.html"><spon class="sectiontitle">Unit Tests</span></a> -
<span class="purpose">Scaffolding code to run unit tests not otherwise represented as inter stages.</span></p>
<span class="purpose">A command-line interface for Inter functions which are not part of the normal operation of the Inform compiler.</span></p>
</li>
</ul>
</li>

View file

@ -3,6 +3,19 @@
A command-line interface for Inbuild functions which are not part of the
normal operation of the Inform compiler.
@h Settings variables.
The following will be set at the command line.
=
pathname *path_to_inbuild = NULL;
int inbuild_task = INSPECT_TTASK;
pathname *path_to_tools = NULL;
int dry_run_mode = FALSE, build_trace_mode = FALSE;
inbuild_nest *destination_nest = NULL;
text_stream *filter_text = NULL;
text_stream *unit_test = NULL;
@h Main routine.
When Inbuild is called at the command line, it begins at |main|, like all C
programs.
@ -14,14 +27,6 @@ set the following variables as needed, and produce a list of targets to work
on; then to carry out that work, and then shut down again.
=
int inbuild_task = INSPECT_TTASK;
pathname *path_to_inbuild = NULL;
pathname *path_to_tools = NULL;
int dry_run_mode = FALSE, build_trace_mode = FALSE;
inbuild_nest *destination_nest = NULL;
text_stream *filter_text = NULL;
text_stream *unit_test = NULL;
int main(int argc, char **argv) {
@<Start up the modules@>;
@<Read the command line@>;

View file

@ -1,30 +1,133 @@
[Main::] Main.
The top level, which decides what is to be done and then carries
this plan out.
A command-line interface for Inter functions which are not part of the
normal operation of the Inform compiler.
@h Main routine.
@d INTOOL_NAME "inter"
@ The modules included in |inter| make use of the Inform 7 module |kinds|,
but when we are using |inter| on its own, kinds have no meaning for us.
We are required to create a |kind| type, in order for |kinds| to compile;
but no instances of this kind will ever in fact exist. |K_value| is a
global constant meaning "any kind at all", and that also must exist.
= (early code)
typedef void kind;
kind *K_value = NULL;
@ We need to allocate one additional type of structure in memory, so:
@e inter_file_MT
@h Settings variables.
The following will be set at the command line.
=
ALLOCATE_INDIVIDUALLY(inter_file)
pathname *path_to_inter = NULL;
@
pathname *kit_to_assimilate = NULL;
pathname *domain_path = NULL;
linked_list *inter_file_list = NULL; /* of |filename| */
filename *output_textually = NULL;
filename *output_binarily = NULL;
dictionary *pipeline_vars = NULL;
filename *pipeline_as_file = NULL;
text_stream *pipeline_as_text = NULL;
void Main::add_pipeline_variable(text_stream *name, text_stream *value) {
Str::copy(Dictionaries::create_text(pipeline_vars, name), value);
}
void Main::add_pipeline_variable_from_filename(text_stream *name, filename *F) {
TEMPORARY_TEXT(fullname);
WRITE_TO(fullname, "%f", F);
Main::add_pipeline_variable(name, fullname);
DISCARD_TEXT(fullname);
}
@h Main routine.
When Inter is called at the command line, it begins at |main|, like all C
programs.
Inter can do three different things: assimilate a kit, run a pipeline of
code generation stages, and verify/transcode files of Inter code. In fact,
though, that's really only two different things, because assimilation is
also done with a pipeline.
=
int main(int argc, char **argv) {
@<Start up the modules@>;
@<Begin with an empty file list and variables dictionary@>;
@<Read the command line@>;
if (kit_to_assimilate) @<Set up a pipeline for assimilation@>;
if ((pipeline_as_file) || (pipeline_as_text))
@<Run the pipeline@>
else
@<Read the list of inter files, and perhaps transcode them@>;
@<Shut down the modules@>;
if (Errors::have_occurred()) return 1;
return 0;
}
@<Start up the modules@> =
Foundation::start(); /* must be started first */
ArchModule::start();
InterModule::start();
BuildingModule::start();
CodegenModule::start();
@<Begin with an empty file list and variables dictionary@> =
inter_file_list = NEW_LINKED_LIST(filename);
pipeline_vars = CodeGen::Pipeline::basic_dictionary(I"output.i6");
@ This pipeline is supplied built in to the installation of |inter|. In fact,
it only ever writes the binary form of the code it produces, so only |*out|
is used. But at times in the past it has been useful to debug with the text
form, which would be written to |*outt|.
@<Set up a pipeline for assimilation@> =
inter_architecture *A = CodeGen::Architecture::current();
if (A == NULL) Errors::fatal("no -architecture given");
pathname *path_to_pipelines = Pathnames::subfolder(path_to_inter, I"Pipelines");
pipeline_as_file = Filenames::in_folder(path_to_pipelines, I"assimilate.interpipeline");
pipeline_as_text = NULL;
Main::add_pipeline_variable(I"*kit",
Pathnames::directory_name(kit_to_assimilate));
Main::add_pipeline_variable_from_filename(I"*out",
Architectures::canonical_binary(kit_to_assimilate, A));
Main::add_pipeline_variable_from_filename(I"*outt",
Architectures::canonical_textual(kit_to_assimilate, A));
@<Run the pipeline@> =
if (LinkedLists::len(inter_file_list) > 0)
Errors::fatal("-pipeline-text and -pipeline-file cannot be combined with inter files");
if ((pipeline_as_file) && (pipeline_as_text))
Errors::fatal("-pipeline-text and -pipeline-file are mutually exclusive");
linked_list *inter_paths = NEW_LINKED_LIST(pathname);
if (kit_to_assimilate) ADD_TO_LINKED_LIST(kit_to_assimilate, pathname, inter_paths);
codegen_pipeline *SS;
if (pipeline_as_file)
SS = CodeGen::Pipeline::parse_from_file(pipeline_as_file, pipeline_vars);
else
SS = CodeGen::Pipeline::parse(pipeline_as_text, pipeline_vars);
linked_list *requirements_list = NEW_LINKED_LIST(inter_library);
if (SS) CodeGen::Pipeline::run(domain_path, SS, inter_paths, requirements_list);
else Errors::fatal("pipeline could not be parsed");
@<Read the list of inter files, and perhaps transcode them@> =
inter_tree *I = Inter::Tree::new();
filename *F;
LOOP_OVER_LINKED_LIST(F, filename, inter_file_list) {
if (Inter::Binary::test_file(F))
Inter::Binary::read(I, F);
else
Inter::Textual::read(I, F);
}
if (output_textually) {
text_stream C_struct; text_stream *OUT = &C_struct;
if (STREAM_OPEN_TO_FILE(OUT, output_textually, UTF8_ENC) == FALSE)
Errors::fatal_with_file("unable to open textual inter file for output: %f",
output_textually);
Inter::Textual::write(OUT, I, NULL, 1);
STREAM_CLOSE(OUT);
}
if (output_binarily) Inter::Binary::write(output_binarily, I);
@<Shut down the modules@> =
InterModule::end();
BuildingModule::end();
CodegenModule::end();
ArchModule::end();
Foundation::end(); /* must be ended last */
@h Command line.
@d INTOOL_NAME "inter"
@e TEXTUAL_CLSW
@e BINARY_CLSW
@ -35,27 +138,7 @@ ALLOCATE_INDIVIDUALLY(inter_file)
@e ARCHITECTURE_CLSW
@e ASSIMILATE_CLSW
=
pathname *path_to_inter = NULL;
pathname *path_to_pipelines = NULL;
pathname *kit_path = NULL;
int template_action = -1;
pathname *domain_path = NULL;
filename *output_textually = NULL;
filename *output_binarily = NULL;
filename *unit_test_file = NULL;
dictionary *pipeline_vars = NULL;
filename *pipeline_as_file = NULL;
text_stream *pipeline_as_text = NULL;
linked_list *requirements_list = NULL;
int main(int argc, char **argv) {
@<Start up the modules@>;
path_to_inter = Pathnames::installation_path("INTER_PATH", I"inter");
path_to_pipelines = Pathnames::subfolder(path_to_inter, I"Pipelines");
requirements_list = NEW_LINKED_LIST(inter_library);
@<Read the command line@> =
CommandLine::declare_heading(
L"[[Purpose]]\n\n"
L"usage: inter file1 file2 ... [options]\n");
@ -76,73 +159,21 @@ int main(int argc, char **argv) {
L"generate Inter with architecture X");
CommandLine::declare_switch(ASSIMILATE_CLSW, L"assimilate", 2,
L"assimilate (i.e., build) Inter kit X for the current architecture");
pipeline_vars = CodeGen::Pipeline::basic_dictionary(I"output.i6");
CommandLine::read(argc, argv, NULL, &Main::respond, &Main::add_file);
if (template_action == ASSIMILATE_CLSW) {
inter_architecture *A = CodeGen::Architecture::current();
if (A == NULL) Errors::fatal("no -architecture given");
filename *assim = Architectures::canonical_binary(kit_path, A);
filename *assim_t = Architectures::canonical_textual(kit_path, A);
pipeline_as_file = Filenames::in_folder(path_to_pipelines, I"assimilate.interpipeline");
TEMPORARY_TEXT(fullname);
WRITE_TO(fullname, "%f", assim);
Str::copy(Dictionaries::create_text(pipeline_vars, I"*out"), fullname);
Str::clear(fullname);
WRITE_TO(fullname, "%f", assim_t);
Str::copy(Dictionaries::create_text(pipeline_vars, I"*outt"), fullname);
DISCARD_TEXT(fullname);
Str::copy(Dictionaries::create_text(pipeline_vars, I"*attach"), Pathnames::directory_name(kit_path));
}
Main::act();
@<Shut down the modules@>;
if (Errors::have_occurred()) return 1;
return 0;
}
@<Start up the modules@> =
Foundation::start(); /* must be started first */
ArchModule::start();
InterModule::start();
BuildingModule::start();
CodegenModule::start();
@<Shut down the modules@> =
InterModule::end();
BuildingModule::end();
CodegenModule::end();
ArchModule::end();
Foundation::end(); /* must be ended last */
path_to_inter = Pathnames::installation_path("INTER_PATH", I"inter");
@ =
void Main::respond(int id, int val, text_stream *arg, void *state) {
switch (id) {
case TEXTUAL_CLSW: output_textually = Filenames::from_text(arg); break;
case BINARY_CLSW: output_binarily = Filenames::from_text(arg); pipeline_as_text = NULL; break;
case BINARY_CLSW: output_binarily = Filenames::from_text(arg); break;
case PIPELINE_CLSW: pipeline_as_text = Str::duplicate(arg); break;
case PIPELINE_FILE_CLSW: pipeline_as_file = Filenames::from_text(arg); break;
case PIPELINE_VARIABLE_CLSW: {
match_results mr = Regexp::create_mr();
if (Regexp::match(&mr, arg, L"(%c+)=(%c+)")) {
if (Str::get_first_char(arg) != '*') {
Errors::fatal("-variable names must begin with '*'");
} else {
Str::copy(Dictionaries::create_text(pipeline_vars, mr.exp[0]), mr.exp[1]);
}
} else {
Errors::fatal("-variable should take the form 'name=value'");
}
Regexp::dispose_of(&mr);
break;
}
case DOMAIN_CLSW: domain_path = Pathnames::from_text(arg); pipeline_as_text = NULL; break;
case ASSIMILATE_CLSW: kit_path = Pathnames::from_text(arg);
pipeline_as_text = NULL; template_action = id; break;
case PIPELINE_VARIABLE_CLSW: @<Add a pipeline variable to the dictionary@>; break;
case DOMAIN_CLSW: domain_path = Pathnames::from_text(arg); break;
case ASSIMILATE_CLSW: kit_to_assimilate = Pathnames::from_text(arg); break;
case ARCHITECTURE_CLSW:
if (CodeGen::Architecture::set(arg) == FALSE)
Errors::fatal("no such -architecture");
@ -150,48 +181,31 @@ void Main::respond(int id, int val, text_stream *arg, void *state) {
}
}
@ =
typedef struct inter_file {
struct filename *inter_filename;
MEMORY_MANAGEMENT
} inter_file;
void Main::add_file(int id, text_stream *arg, void *state) {
inter_file *IF = CREATE(inter_file);
IF->inter_filename = Filenames::from_text(arg);
}
@ =
void Main::act(void) {
if ((pipeline_as_file) || (pipeline_as_text)) {
if (NUMBER_CREATED(inter_file) > 0)
Errors::fatal("-pipeline-text and -pipeline-file cannot be combined with inter file parameters");
linked_list *inter_paths = NEW_LINKED_LIST(pathname);
ADD_TO_LINKED_LIST(kit_path, pathname, inter_paths);
codegen_pipeline *SS;
if (pipeline_as_file) SS = CodeGen::Pipeline::parse_from_file(pipeline_as_file, pipeline_vars);
else SS = CodeGen::Pipeline::parse(pipeline_as_text, pipeline_vars);
if (SS) CodeGen::Pipeline::run(domain_path, SS, inter_paths, requirements_list);
else Errors::fatal("pipeline could not be parsed");
} else if (unit_test_file) {
UnitTests::run(unit_test_file);
@<Add a pipeline variable to the dictionary@> =
match_results mr = Regexp::create_mr();
if (Regexp::match(&mr, arg, L"(%c+)=(%c+)")) {
if (Str::get_first_char(arg) != '*') {
Errors::fatal("-variable names must begin with '*'");
} else {
Main::add_pipeline_variable(mr.exp[0], mr.exp[1]);
}
} else {
inter_tree *I = Inter::Tree::new();
inter_file *IF;
LOOP_OVER(IF, inter_file) {
if (Inter::Binary::test_file(IF->inter_filename))
Inter::Binary::read(I, IF->inter_filename);
else
Inter::Textual::read(I, IF->inter_filename);
}
if (output_textually) {
text_stream C_struct; text_stream *OUT = &C_struct;
if (STREAM_OPEN_TO_FILE(OUT, output_textually, UTF8_ENC) == FALSE)
Errors::fatal_with_file("unable to open textual inter file for output: %f",
output_textually);
Inter::Textual::write(OUT, I, NULL, 1);
STREAM_CLOSE(OUT);
}
if (output_binarily) Inter::Binary::write(output_binarily, I);
Errors::fatal("-variable should take the form 'name=value'");
}
Regexp::dispose_of(&mr);
@ =
void Main::add_file(int id, text_stream *arg, void *state) {
filename *F = Filenames::from_text(arg);
ADD_TO_LINKED_LIST(F, filename, inter_file_list);
}
@ The modules included in |inter| make use of the Inform 7 module |kinds|,
but when we are using |inter| on its own, kinds have no meaning for us.
We are required to create a |kind| type, in order for |kinds| to compile;
but no instances of this kind will ever in fact exist. |K_value| is a
global constant meaning "any kind at all", and that also must exist.
= (early code)
typedef void kind;
kind *K_value = NULL;

View file

@ -1,73 +0,0 @@
[UnitTests::] Unit Tests.
Scaffolding code to run unit tests not otherwise represented as inter stages.
@
=
void UnitTests::run(filename *F) {
inter_tree *dummy = Inter::Tree::new();
inter_bookmark IBM = Inter::Bookmarks::at_start_of_this_repository(dummy);
Primitives::emit(dummy, &IBM);
Streams::enable_debugging(STDOUT);
text_stream *FORMER_DL = DL;
DL = STDOUT;
inter_unit_test iut;
iut.to_perform = NO_IUT;
iut.test_input = Str::new();
TextFiles::read(F, FALSE, "unable to read tests file", TRUE,
&UnitTests::test_harvester, NULL, &iut);
Streams::disable_debugging(STDOUT);
DL = FORMER_DL;
}
@
@e NO_IUT from 0
@e SCHEMA_IUT
@e SCHEMA_WORKINGS_IUT
typedef struct inter_unit_test {
int to_perform;
struct text_stream *test_input;
} inter_unit_test;
void UnitTests::test_harvester(text_stream *text, text_file_position *tfp, void *v_iut) {
inter_unit_test *iut = (inter_unit_test *) v_iut;
if (Str::eq(text, I"schema")) {
iut->to_perform = SCHEMA_IUT;
Str::clear(iut->test_input);
} else if (Str::eq(text, I"schema-workings")) {
iut->to_perform = SCHEMA_WORKINGS_IUT;
Str::clear(iut->test_input);
} else if (Str::eq(text, I"end")) {
switch (iut->to_perform) {
case SCHEMA_WORKINGS_IUT:
Log::set_aspect(SCHEMA_COMPILATION_DETAILS_DA, TRUE);
@<Perform the schema test@>;
Log::set_aspect(SCHEMA_COMPILATION_DETAILS_DA, FALSE);
break;
case SCHEMA_IUT:
@<Perform the schema test@>;
break;
default: Errors::in_text_file("unimplemented test", tfp); break;
}
iut->to_perform = NO_IUT;
} else {
if (iut->to_perform == NO_IUT) {
if (Str::len(text) == 0) return;
Errors::in_text_file("content outside of test", tfp);
} else {
WRITE_TO(iut->test_input, "%S\n", text);
}
}
}
@<Perform the schema test@> =
LOG("Test: parse schema from:\n%S\n", iut->test_input);
Str::trim_white_space(iut->test_input);
inter_schema *sch = InterSchemas::from_text(iut->test_input, FALSE, 0, NULL);
if (sch == NULL) LOG("<null schema>\n");
else if (sch->node_tree == NULL) LOG("<nodeless scheme\n");
else InterSchemas::log(DL, sch);
LOG("=========\n");

View file

@ -27,4 +27,3 @@ Manual
Chapter 1: Outside of inform7
Main
Unit Tests

View file

@ -1,4 +1,4 @@
prepare <- *attach
prepare <- *kit
merge-template <- all
parse-linked-matter
resolve-conditional-compilation

View file

@ -0,0 +1,21 @@
packagetype _plain
packagetype _code
packagetype _linkage
primitive !if val code -> void
primitive !goto lab -> void
package main _plain
symbol public misc K_number
symbol public misc K_func
symbol public misc awkward
symbol public misc troublesome
symbol external misc secret --> /main/my_fn/secret
kind K_number int32
kind K_func function K_number -> K_number
# Exported my_fn here
constant awkward K_number = secret
constant troublesome K_number = 12
package connectors _linkage
symbol socket misc secret --> /main/my_fn/secret
symbol plug misc plug00002 --? C_majors

View file

@ -0,0 +1,197 @@
# This is a miscellany of tests.
packagetype _plain
packagetype _code
packagetype _linkage
version 7
primitive !return val -> void
primitive !modulo val val -> val
primitive !plus val val -> val
primitive !if val code -> void
primitive !goto lab -> void
pragma target_I6 "$MAX_STATIC_DATA=180000"
package main _plain
symbol public misc K_number
symbol public misc K_truth_state
symbol public misc V_banana
symbol public misc C_death
symbol public misc C_taxes
symbol public misc V_anxiety
symbol public misc C_x
symbol public misc cornelius
symbol public misc gaius
symbol public misc mark_my_words
symbol external misc peach
symbol public misc K_colour
symbol public misc I_green
symbol public misc I_red
symbol public misc V_shade
symbol public misc K_list_of_number
symbol public misc C_primes
symbol public misc C_concealed
symbol public misc V_watch_list
symbol public misc 718_varieties
symbol public misc K_text
symbol public misc C_complaint
symbol public misc C_raw
symbol public misc K_odour
symbol public misc I_citrus
symbol public misc I_leather
symbol public misc P_strength
symbol public misc pp_auto_1
symbol public misc P_lingeringness
symbol public misc pp_auto_2
symbol public misc K_table
symbol public misc K_column_of_number
symbol public misc K_column_of_colour
symbol public misc C_egtable_col1
symbol public misc C_egtable_col2
symbol public misc C_egtable
symbol public misc K_object
symbol public misc I_board
symbol public misc K_piece
symbol public misc I_bishop
symbol public misc I_rook
symbol public misc K_list_of_objects
symbol public misc C_majors
symbol public misc pp_auto_3
symbol public misc K_func
symbol public misc K_rule
symbol public misc K_rulebook
symbol public misc K_stuff
symbol public misc S_stuff
symbol public misc R_after1
symbol public misc R_after2
symbol public misc RB_after
symbol public misc K_colour____colour
symbol public misc R_101
symbol public misc R_102
symbol public misc amount
symbol public misc R_101_A
kind K_number int32
kind K_truth_state int2
defaultvalue K_number = 47
variable V_banana K_number = 100
constant C_death K_number = -5
constant C_taxes K_number = 14
variable V_anxiety K_number = C_death
constant C_x K_number = 0x7f2a __hex
link early "alpha" "beta" "gamma" "delta"
link before "alpha" "" "" ""
link instead "" "beta" "" ""
link after "" "" "gamma" ""
constant cornelius K_number = dw'frogs'
constant gaius K_number = dw'toads'
splat &"Sing a song of \"six splats\"...\nand don't wait up"
kind K_colour enum
instance I_green K_colour = 1
instance I_red K_colour = 17
variable V_shade K_colour = I_red
kind K_list_of_number list of K_number
constant C_primes K_list_of_number = { 2, 3, 5, 7, 11, 13, 17, 19 }
constant C_concealed K_list_of_number = C_primes
variable V_watch_list K_list_of_number = C_concealed
kind K_text text
constant C_complaint K_text = "This is already quite a long test case."
constant C_raw K_number = &"SOME_I6_DRIVEL"
kind K_odour enum
instance I_citrus K_odour = 5
instance I_leather K_odour = 10
property P_strength K_number __property_name="strength"
permission P_strength K_odour
propertyvalue P_strength I_citrus = 20
propertyvalue P_strength I_leather = 7
property P_lingeringness K_number
permission P_lingeringness K_odour
propertyvalue P_lingeringness I_citrus = 1
propertyvalue P_lingeringness I_leather = 3
propertyvalue P_lingeringness K_odour = 2
kind K_table table
kind K_column_of_number column of K_number
kind K_column_of_colour column of K_colour
constant C_egtable_col1 K_column_of_number = { 1, 4, 9, 16 }
constant C_egtable_col2 K_column_of_colour = { I_green, undef, I_red }
constant C_egtable K_table = { C_egtable_col1, C_egtable_col2 }
kind K_object enum
instance I_board K_object = 1
kind K_piece <= K_object
instance I_bishop K_piece = 2
instance I_rook K_piece = 3
kind K_list_of_objects list of K_object
constant C_majors K_list_of_objects = { I_bishop, I_rook }
permission P_lingeringness I_bishop
kind K_func function K_colour K_number -> K_odour
kind K_rule rule void -> void
kind K_rulebook rulebook of K_rule
kind K_stuff struct K_number K_colour K_odour
constant S_stuff K_stuff = { 5, I_red, I_citrus }
package R_after1_B _code
package R_after2_B _code
constant R_after1 K_rule = R_after1_B
constant R_after2 K_rule = R_after2_B
constant RB_after K_rulebook = { R_after1, R_after2 }
kind K_colour____colour function K_colour -> K_colour
package R_101_B _code
symbol private misc x
symbol external misc K_colour --> /main/K_colour
symbol external misc R_102 --> /main/R_102
symbol external misc I_green --> /main/I_green
symbol external misc K_number --> /main/K_number
symbol external misc K_truth_state --> /main/K_truth_state
local x K_colour __call_parameter
code
inv R_102
val K_colour I_green
inv !return
inv !modulo
inv !plus
cast K_number <- K_colour
val K_colour x
val K_number 1
val K_truth_state &"a b"
constant R_101 K_colour____colour = R_101_B
package R_102_B _code
symbol private misc x
symbol external misc K_colour --> /main/K_colour
symbol external misc I_red --> /main/I_red
local x K_colour __call_parameter
code
inv !return
val K_colour I_red
constant R_102 K_colour____colour = R_102_B
constant amount K_number = sum{ 2, C_taxes }
response R_101_A R_101 0 = C_taxes
package connectors _linkage
symbol socket misc C_majors --> /main/C_majors
symbol plug misc plug_00001 --? secret
symbol plug misc plug_00001_1 --? C_majors
symbol plug misc plug_00002 --? /main/troublesome
symbol socket misc secret --> /main/connectors/secret
# Imported my_fn here
package my_fn _plain
symbol public misc R_101
symbol public misc secret
symbol external misc K_func --> /main/K_func
symbol external misc K_number --> /main/K_number
symbol external misc plug00002 --> /main/connectors/plug_00001_1
symbol public misc tricksy
package R_101_B _code
symbol private misc x
symbol private label .begin
symbol external misc K_number --> /main/K_number
symbol external misc troublesome --> /main/connectors/plug_00002
local x K_number __call_parameter
code
.begin
inv !if
val K_number plug_00002
code
inv !goto
lab .begin
constant R_101 K_func = R_101_B
constant secret K_number = 7
constant tricksy K_number = plug_00001_1

View file

@ -59,7 +59,7 @@
mkdir: $PATH/_Results_Ideal
mkdir: $PATH/_Console
step: inter/Tangled/inter -architecture 16d -template inform7/Internal/I6T/standard_rules -variable '*in=$O' -variable '*out=$A' -pipeline-file $P >$T 2>&1
step: inter/Tangled/inter -architecture 16d -variable '*in=$O' -variable '*out=$A' -pipeline-file $P >$T 2>&1
or: 'failed to produce output' $T
show: $A
@ -87,7 +87,7 @@
mkdir: $PATH/_Console
mkdir: $PATH/_Binaries
step: inter/Tangled/inter -template inform7/Internal/I6T -variable '*inA=$OA' -variable '*inB=$OB' -variable '*binA=$BA' -variable '*binB=$BB' -variable '*outA=$AA' -variable '*outB=$AB' -pipeline-file $P >$T 2>&1
step: inter/Tangled/inter -variable '*inA=$OA' -variable '*inB=$OB' -variable '*binA=$BA' -variable '*binB=$BB' -variable '*outA=$AA' -variable '*outB=$AB' -pipeline-file $P >$T 2>&1
or: 'failed to produce output' $T
show: $A
@ -110,7 +110,7 @@
mkdir: $PATH/_Results_Actual
mkdir: $PATH/_Results_Ideal
fail step: inter/Tangled/inter -template inform7/Internal/I6T -variable '*in=$O' -pipeline-file $P >$A 2>&1
fail step: inter/Tangled/inter -variable '*in=$O' -pipeline-file $P >$A 2>&1
or: 'failed to produce errors' $A
show: $A