1
0
Fork 0
mirror of https://github.com/ganelson/inform.git synced 2024-07-16 22:14:23 +03:00
inform7/docs/codegen-module/4-cg.html

321 lines
34 KiB
HTML
Raw Normal View History

2019-03-17 14:40:57 +02:00
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>3/is</title>
2019-03-17 14:40:57 +02:00
<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>
<!--Weave of '4/cg' generated by 7-->
<ul class="crumbs"><li><a href="../webs.html">&#9733;</a></li><li><a href="index.html">codegen</a></li><li><a href="index.html#4">Chapter 4: Inter to Final Code</a></li><li><b>Code Generation</b></li></ul><p class="purpose">To generate final code from intermediate code.</p>
2019-03-17 14:40:57 +02:00
2019-06-29 15:17:29 +03:00
<ul class="toc"><li><a href="#SP1">&#167;1. Pipeline stage</a></li><li><a href="#SP2">&#167;2. Generations</a></li><li><a href="#SP8">&#167;8. </a></li><li><a href="#SP9">&#167;9. Marking</a></li></ul><hr class="tocbar">
2019-03-17 14:40:57 +02:00
<p class="inwebparagraph"><a id="SP1"></a><b>&#167;1. Pipeline stage. </b></p>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">CodeGen::create_pipeline_stage</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
<span class="functiontext">CodeGen::Stage::new</span><span class="plain">(</span><span class="identifier">I</span><span class="string">"generate"</span><span class="plain">, </span><span class="functiontext">CodeGen::run_pipeline_stage</span><span class="plain">, </span><span class="constant">TEXT_OUT_STAGE_ARG</span><span class="plain">);</span>
<span class="plain">}</span>
2019-06-11 02:38:15 +03:00
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">CodeGen::run_pipeline_stage</span><span class="plain">(</span><span class="reserved">pipeline_step</span><span class="plain"> *</span><span class="identifier">step</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">step</span><span class="plain">-</span><span class="element">&gt;target_argument</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"no target specified"</span><span class="plain">);</span>
2019-06-29 19:36:49 +03:00
<span class="identifier">inter_package</span><span class="plain"> *</span><span class="identifier">which</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">Str::len</span><span class="plain">(</span><span class="identifier">step</span><span class="plain">-</span><span class="element">&gt;package_argument</span><span class="plain">) &gt; 0) {</span>
<span class="identifier">inter_symbol</span><span class="plain"> *</span><span class="identifier">symb</span><span class="plain"> = </span><span class="identifier">Inter::SymbolsTables::url_name_to_symbol</span><span class="plain">(</span><span class="identifier">step</span><span class="plain">-</span><span class="element">&gt;repository</span><span class="plain">,</span>
<span class="identifier">NULL</span><span class="plain">, </span><span class="identifier">step</span><span class="plain">-</span><span class="element">&gt;package_argument</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">symb</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">"Arg %S\</span><span class="plain">n</span><span class="string">"</span><span class="plain">, </span><span class="identifier">step</span><span class="plain">-</span><span class="element">&gt;package_argument</span><span class="plain">);</span>
<span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"no such package name"</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="identifier">which</span><span class="plain"> = </span><span class="identifier">Inter::Package::which</span><span class="plain">(</span><span class="identifier">symb</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">which</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">"Arg %S\</span><span class="plain">n</span><span class="string">"</span><span class="plain">, </span><span class="identifier">step</span><span class="plain">-</span><span class="element">&gt;package_argument</span><span class="plain">);</span>
<span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"that's not a package name"</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="plain">}</span>
2019-06-29 15:17:29 +03:00
<span class="reserved">code_generation</span><span class="plain"> *</span><span class="identifier">gen</span><span class="plain"> =</span>
2019-06-29 19:36:49 +03:00
<span class="functiontext">CodeGen::new_generation</span><span class="plain">(</span><span class="identifier">step</span><span class="plain">, </span><span class="identifier">step</span><span class="plain">-</span><span class="element">&gt;repository</span><span class="plain">, </span><span class="identifier">which</span><span class="plain">, </span><span class="identifier">step</span><span class="plain">-</span><span class="element">&gt;target_argument</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">CodeGen::Targets::begin_generation</span><span class="plain">(</span><span class="identifier">gen</span><span class="plain">) == </span><span class="identifier">FALSE</span><span class="plain">) {</span>
2019-06-27 01:50:30 +03:00
<span class="functiontext">CodeGen::generate</span><span class="plain">(</span><span class="identifier">gen</span><span class="plain">);</span>
<span class="functiontext">CodeGen::write</span><span class="plain">(</span><span class="identifier">step</span><span class="plain">-</span><span class="element">&gt;text_out_file</span><span class="plain">, </span><span class="identifier">gen</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function CodeGen::create_pipeline_stage is used in 1/stg (<a href="1-stg.html#SP2">&#167;2</a>).</p>
<p class="endnote">The function CodeGen::run_pipeline_stage appears nowhere else.</p>
2019-06-27 01:50:30 +03:00
<p class="inwebparagraph"><a id="SP2"></a><b>&#167;2. Generations. </b>A "generation" is a single act of translating inter code into final code.
That final code will be a text file written in some other programming
language, though probably a low-level one.
</p>
<p class="inwebparagraph">The "target" of a generation is the final language: for example, Inform 6.
</p>
<p class="inwebparagraph">During a generation, textual output is assembled as a set of "segments".
Different targets may need different segments. This is all to facilitate
rearranging content as necessary to get it to compile in the target language:
for example, one might need to have all constants defined first, then all
arrays, and one could do this by creating two segments, one to accumulate
the constants in, one to accumulate the arrays.
</p>
2019-06-29 15:17:29 +03:00
<p class="inwebparagraph">At any given time, a generation has a "current" segment, to which output
is being written. Ome segment is special: the temporary one, which is used
only when assembling other material, and not for the final output.
</p>
2019-06-27 01:50:30 +03:00
<pre class="definitions">
<span class="definitionkeyword">define</span> <span class="constant">MAX_CG_SEGMENTS</span><span class="plain"> 100</span>
2019-06-27 12:41:37 +03:00
<span class="definitionkeyword">define</span> <span class="constant">TEMP_CG_SEGMENT</span><span class="plain"> 99</span>
2019-06-27 01:50:30 +03:00
</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">code_generation</span><span class="plain"> {</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">pipeline_step</span><span class="plain"> *</span><span class="identifier">from_step</span><span class="plain">;</span>
2019-06-27 01:50:30 +03:00
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">inter_repository</span><span class="plain"> *</span><span class="identifier">from</span><span class="plain">;</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">code_generation_target</span><span class="plain"> *</span><span class="identifier">target</span><span class="plain">;</span>
2019-06-29 19:36:49 +03:00
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">inter_package</span><span class="plain"> *</span><span class="identifier">just_this_package</span><span class="plain">;</span>
2019-06-27 01:50:30 +03:00
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">generated_segment</span><span class="plain"> *</span><span class="identifier">segments</span><span class="plain">[</span><span class="constant">MAX_CG_SEGMENTS</span><span class="plain">];</span>
2019-06-29 15:17:29 +03:00
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">generated_segment</span><span class="plain"> *</span><span class="identifier">current_segment</span><span class="plain">; </span> <span class="comment">an entry in that array, or null</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">temporarily_diverted</span><span class="plain">; </span> <span class="comment">to the temporary segment</span>
2019-06-27 01:50:30 +03:00
<span class="identifier">MEMORY_MANAGEMENT</span>
<span class="plain">} </span><span class="reserved">code_generation</span><span class="plain">;</span>
2019-06-29 15:17:29 +03:00
<span class="reserved">code_generation</span><span class="plain"> *</span><span class="functiontext">CodeGen::new_generation</span><span class="plain">(</span><span class="reserved">pipeline_step</span><span class="plain"> *</span><span class="identifier">step</span><span class="plain">, </span><span class="identifier">inter_repository</span><span class="plain"> *</span><span class="identifier">I</span><span class="plain">,</span>
2019-06-29 19:36:49 +03:00
<span class="identifier">inter_package</span><span class="plain"> *</span><span class="identifier">just</span><span class="plain">, </span><span class="reserved">code_generation_target</span><span class="plain"> *</span><span class="identifier">target</span><span class="plain">) {</span>
2019-06-27 01:50:30 +03:00
<span class="reserved">code_generation</span><span class="plain"> *</span><span class="identifier">gen</span><span class="plain"> = </span><span class="identifier">CREATE</span><span class="plain">(</span><span class="reserved">code_generation</span><span class="plain">);</span>
<span class="identifier">gen</span><span class="plain">-</span><span class="element">&gt;from_step</span><span class="plain"> = </span><span class="identifier">step</span><span class="plain">;</span>
2019-06-27 01:50:30 +03:00
<span class="identifier">gen</span><span class="plain">-</span><span class="element">&gt;from</span><span class="plain"> = </span><span class="identifier">I</span><span class="plain">;</span>
<span class="identifier">gen</span><span class="plain">-</span><span class="element">&gt;target</span><span class="plain"> = </span><span class="identifier">target</span><span class="plain">;</span>
2019-06-29 19:36:49 +03:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">just</span><span class="plain">) </span><span class="identifier">gen</span><span class="plain">-</span><span class="element">&gt;just_this_package</span><span class="plain"> = </span><span class="identifier">just</span><span class="plain">;</span>
<span class="reserved">else</span><span class="plain"> </span><span class="identifier">gen</span><span class="plain">-</span><span class="element">&gt;just_this_package</span><span class="plain"> = </span><span class="identifier">Inter::Packages::main</span><span class="plain">(</span><span class="identifier">I</span><span class="plain">);</span>
2019-06-27 01:50:30 +03:00
<span class="identifier">gen</span><span class="plain">-</span><span class="element">&gt;current_segment</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
2019-06-27 12:41:37 +03:00
<span class="identifier">gen</span><span class="plain">-</span><span class="element">&gt;temporarily_diverted</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
2019-06-27 01:50:30 +03:00
<span class="reserved">for</span><span class="plain"> (</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">i</span><span class="plain">=0; </span><span class="identifier">i</span><span class="plain">&lt;</span><span class="constant">MAX_CG_SEGMENTS</span><span class="plain">; </span><span class="identifier">i</span><span class="plain">++) </span><span class="identifier">gen</span><span class="plain">-</span><span class="element">&gt;segments</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">] = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">gen</span><span class="plain">;</span>
<span class="plain">}</span>
2019-06-29 15:17:29 +03:00
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function CodeGen::new_generation is used in <a href="#SP1">&#167;1</a>, 4/fc (<a href="4-fc.html#SP3">&#167;3</a>).</p>
<p class="endnote">The structure code_generation is accessed in 4/fc, 4/cal, 4/iap, 4/vrb, 5/ft, 5/fti, 5/fbi, 5/fi, 5/fsi, 5/gi6 and here.</p>
<p class="inwebparagraph"><a id="SP3"></a><b>&#167;3. </b>At present, at least, a "segment" is nothing more than a wrapper for a text.
But we abstract it in case it's ever useful for it to be more.
</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">generated_segment</span><span class="plain"> {</span>
<span class="reserved">struct</span><span class="plain"> </span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">generated_code</span><span class="plain">;</span>
<span class="identifier">MEMORY_MANAGEMENT</span>
<span class="plain">} </span><span class="reserved">generated_segment</span><span class="plain">;</span>
2019-06-27 01:50:30 +03:00
<span class="reserved">generated_segment</span><span class="plain"> *</span><span class="functiontext">CodeGen::new_segment</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
<span class="reserved">generated_segment</span><span class="plain"> *</span><span class="identifier">seg</span><span class="plain"> = </span><span class="identifier">CREATE</span><span class="plain">(</span><span class="reserved">generated_segment</span><span class="plain">);</span>
<span class="identifier">seg</span><span class="plain">-</span><span class="element">&gt;generated_code</span><span class="plain"> = </span><span class="identifier">Str::new</span><span class="plain">();</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">seg</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
2019-06-29 15:17:29 +03:00
<p class="endnote">The function CodeGen::new_segment is used in <a href="#SP6">&#167;6</a>, 5/gi6 (<a href="5-gi6.html#SP2">&#167;2</a>).</p>
2019-06-27 01:50:30 +03:00
2019-06-29 15:17:29 +03:00
<p class="endnote">The structure generated_segment is private to this section.</p>
2019-06-27 01:50:30 +03:00
2019-06-29 15:17:29 +03:00
<p class="inwebparagraph"><a id="SP4"></a><b>&#167;4. </b>The segments should be numbered in the order they will appear in the final
output, because:
</p>
2019-06-27 01:50:30 +03:00
2019-06-29 15:17:29 +03:00
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">CodeGen::write</span><span class="plain">(</span><span class="identifier">OUTPUT_STREAM</span><span class="plain">, </span><span class="reserved">code_generation</span><span class="plain"> *</span><span class="identifier">gen</span><span class="plain">) {</span>
<span class="reserved">for</span><span class="plain"> (</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">i</span><span class="plain">=0; </span><span class="identifier">i</span><span class="plain">&lt;</span><span class="constant">MAX_CG_SEGMENTS</span><span class="plain">; </span><span class="identifier">i</span><span class="plain">++)</span>
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">gen</span><span class="plain">-</span><span class="element">&gt;segments</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">]) &amp;&amp; (</span><span class="identifier">i</span><span class="plain"> != </span><span class="constant">TEMP_CG_SEGMENT</span><span class="plain">))</span>
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"%S"</span><span class="plain">, </span><span class="identifier">gen</span><span class="plain">-</span><span class="element">&gt;segments</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">]-</span><span class="element">&gt;generated_code</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function CodeGen::write is used in <a href="#SP1">&#167;1</a>.</p>
<p class="inwebparagraph"><a id="SP5"></a><b>&#167;5. </b>Here we switch the output, by changing the segment selection. This must
always be done in a way which is then undone, restoring the previous state:
</p>
2019-03-17 14:40:57 +02:00
<pre class="display">
2019-06-27 12:41:37 +03:00
<span class="reserved">generated_segment</span><span class="plain"> *</span><span class="functiontext">CodeGen::select</span><span class="plain">(</span><span class="reserved">code_generation</span><span class="plain"> *</span><span class="identifier">gen</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">i</span><span class="plain">) {</span>
<span class="reserved">generated_segment</span><span class="plain"> *</span><span class="identifier">saved</span><span class="plain"> = </span><span class="identifier">gen</span><span class="plain">-</span><span class="element">&gt;current_segment</span><span class="plain">;</span>
2019-06-27 01:50:30 +03:00
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">i</span><span class="plain"> &lt; 0) || (</span><span class="identifier">i</span><span class="plain"> &gt;= </span><span class="constant">MAX_CG_SEGMENTS</span><span class="plain">)) </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"out of range"</span><span class="plain">);</span>
2019-06-27 12:41:37 +03:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">gen</span><span class="plain">-</span><span class="element">&gt;temporarily_diverted</span><span class="plain">) </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"poorly timed selection"</span><span class="plain">);</span>
2019-06-27 01:50:30 +03:00
<span class="identifier">gen</span><span class="plain">-</span><span class="element">&gt;current_segment</span><span class="plain"> = </span><span class="identifier">gen</span><span class="plain">-</span><span class="element">&gt;segments</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">];</span>
2019-06-27 12:41:37 +03:00
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">saved</span><span class="plain">;</span>
2019-06-27 01:50:30 +03:00
<span class="plain">}</span>
2019-06-29 15:17:29 +03:00
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">CodeGen::deselect</span><span class="plain">(</span><span class="reserved">code_generation</span><span class="plain"> *</span><span class="identifier">gen</span><span class="plain">, </span><span class="reserved">generated_segment</span><span class="plain"> *</span><span class="identifier">saved</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">gen</span><span class="plain">-</span><span class="element">&gt;temporarily_diverted</span><span class="plain">) </span><span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"poorly timed deselection"</span><span class="plain">);</span>
<span class="identifier">gen</span><span class="plain">-</span><span class="element">&gt;current_segment</span><span class="plain"> = </span><span class="identifier">saved</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function CodeGen::select is used in 4/fc (<a href="4-fc.html#SP2">&#167;2</a>), 4/cal (<a href="4-cal.html#SP2_1">&#167;2.1</a>, <a href="4-cal.html#SP2_2">&#167;2.2</a>, <a href="4-cal.html#SP3">&#167;3</a>), 4/iap (<a href="4-iap.html#SP1">&#167;1</a>, <a href="4-iap.html#SP4_5">&#167;4.5</a>, <a href="4-iap.html#SP4_6">&#167;4.6</a>, <a href="4-iap.html#SP5">&#167;5</a>), 5/gi6 (<a href="5-gi6.html#SP5">&#167;5</a>, <a href="5-gi6.html#SP6">&#167;6</a>).</p>
<p class="endnote">The function CodeGen::deselect is used in 4/fc (<a href="4-fc.html#SP2">&#167;2</a>), 4/cal (<a href="4-cal.html#SP2_1">&#167;2.1</a>, <a href="4-cal.html#SP2_2">&#167;2.2</a>, <a href="4-cal.html#SP3">&#167;3</a>), 4/iap (<a href="4-iap.html#SP1">&#167;1</a>, <a href="4-iap.html#SP4_5">&#167;4.5</a>, <a href="4-iap.html#SP4_6">&#167;4.6</a>, <a href="4-iap.html#SP5">&#167;5</a>), 5/gi6 (<a href="5-gi6.html#SP5">&#167;5</a>, <a href="5-gi6.html#SP6">&#167;6</a>).</p>
<p class="inwebparagraph"><a id="SP6"></a><b>&#167;6. </b>The procedure for selecting the temporary segment is different, because
we also have to direct it to a given text.
</p>
<pre class="display">
2019-06-27 12:41:37 +03:00
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">CodeGen::select_temporary</span><span class="plain">(</span><span class="reserved">code_generation</span><span class="plain"> *</span><span class="identifier">gen</span><span class="plain">, </span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">T</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">gen</span><span class="plain">-</span><span class="element">&gt;segments</span><span class="plain">[</span><span class="constant">TEMP_CG_SEGMENT</span><span class="plain">] == </span><span class="identifier">NULL</span><span class="plain">) {</span>
<span class="identifier">gen</span><span class="plain">-</span><span class="element">&gt;segments</span><span class="plain">[</span><span class="constant">TEMP_CG_SEGMENT</span><span class="plain">] = </span><span class="functiontext">CodeGen::new_segment</span><span class="plain">();</span>
<span class="identifier">gen</span><span class="plain">-</span><span class="element">&gt;segments</span><span class="plain">[</span><span class="constant">TEMP_CG_SEGMENT</span><span class="plain">]-</span><span class="element">&gt;generated_code</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">gen</span><span class="plain">-</span><span class="element">&gt;temporarily_diverted</span><span class="plain">)</span>
<span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"nested temporary cgs"</span><span class="plain">);</span>
<span class="identifier">gen</span><span class="plain">-</span><span class="element">&gt;temporarily_diverted</span><span class="plain"> = </span><span class="identifier">TRUE</span><span class="plain">;</span>
<span class="identifier">gen</span><span class="plain">-</span><span class="element">&gt;segments</span><span class="plain">[</span><span class="constant">TEMP_CG_SEGMENT</span><span class="plain">]-</span><span class="element">&gt;generated_code</span><span class="plain"> = </span><span class="identifier">T</span><span class="plain">;</span>
2019-06-27 01:50:30 +03:00
<span class="plain">}</span>
2019-06-27 12:41:37 +03:00
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">CodeGen::deselect_temporary</span><span class="plain">(</span><span class="reserved">code_generation</span><span class="plain"> *</span><span class="identifier">gen</span><span class="plain">) {</span>
<span class="identifier">gen</span><span class="plain">-</span><span class="element">&gt;temporarily_diverted</span><span class="plain"> = </span><span class="identifier">FALSE</span><span class="plain">;</span>
2019-06-27 01:50:30 +03:00
<span class="plain">}</span>
2019-06-29 15:17:29 +03:00
</pre>
<p class="inwebparagraph"></p>
2019-06-27 01:50:30 +03:00
2019-06-29 15:17:29 +03:00
<p class="endnote">The function CodeGen::select_temporary is used in 4/fc (<a href="4-fc.html#SP2">&#167;2</a>, <a href="4-fc.html#SP3">&#167;3</a>), 4/iap (<a href="4-iap.html#SP5_8_4_1_1">&#167;5.8.4.1.1</a>).</p>
<p class="endnote">The function CodeGen::deselect_temporary is used in 4/fc (<a href="4-fc.html#SP2">&#167;2</a>, <a href="4-fc.html#SP3">&#167;3</a>), 4/iap (<a href="4-iap.html#SP5_8_4_1_1">&#167;5.8.4.1.1</a>).</p>
<p class="inwebparagraph"><a id="SP7"></a><b>&#167;7. </b>Note that temporary selections take precedence over the regular selection.
</p>
<pre class="display">
2019-06-27 01:50:30 +03:00
<span class="identifier">text_stream</span><span class="plain"> *</span><span class="functiontext">CodeGen::current</span><span class="plain">(</span><span class="reserved">code_generation</span><span class="plain"> *</span><span class="identifier">gen</span><span class="plain">) {</span>
2019-06-29 15:17:29 +03:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">gen</span><span class="plain">-</span><span class="element">&gt;temporarily_diverted</span><span class="plain">)</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">gen</span><span class="plain">-</span><span class="element">&gt;segments</span><span class="plain">[</span><span class="constant">TEMP_CG_SEGMENT</span><span class="plain">]-</span><span class="element">&gt;generated_code</span><span class="plain">;</span>
2019-06-27 01:50:30 +03:00
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">gen</span><span class="plain">-</span><span class="element">&gt;current_segment</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="reserved">return</span><span class="plain"> </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">gen</span><span class="plain">-</span><span class="element">&gt;current_segment</span><span class="plain">-</span><span class="element">&gt;generated_code</span><span class="plain">;</span>
<span class="plain">}</span>
2019-06-29 15:17:29 +03:00
</pre>
2019-06-27 01:50:30 +03:00
2019-06-29 15:17:29 +03:00
<p class="inwebparagraph"></p>
<p class="endnote">The function CodeGen::current is used in 4/fc (<a href="4-fc.html#SP2">&#167;2</a>, <a href="4-fc.html#SP3">&#167;3</a>, <a href="4-fc.html#SP4">&#167;4</a>), 4/cal (<a href="4-cal.html#SP2_1">&#167;2.1</a>, <a href="4-cal.html#SP2_2">&#167;2.2</a>, <a href="4-cal.html#SP3">&#167;3</a>), 4/iap (<a href="4-iap.html#SP1">&#167;1</a>, <a href="4-iap.html#SP4_5">&#167;4.5</a>, <a href="4-iap.html#SP4_6">&#167;4.6</a>, <a href="4-iap.html#SP5">&#167;5</a>, <a href="4-iap.html#SP6">&#167;6</a>, <a href="4-iap.html#SP8">&#167;8</a>), 5/gi6 (<a href="5-gi6.html#SP2">&#167;2</a>, <a href="5-gi6.html#SP3">&#167;3</a>, <a href="5-gi6.html#SP4">&#167;4</a>, <a href="5-gi6.html#SP5">&#167;5</a>, <a href="5-gi6.html#SP6">&#167;6</a>).</p>
2019-06-27 01:50:30 +03:00
2019-06-29 15:17:29 +03:00
<p class="inwebparagraph"><a id="SP8"></a><b>&#167;8. </b>Actual generation happens in three phases:
</p>
<pre class="display">
2019-06-27 01:50:30 +03:00
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">CodeGen::generate</span><span class="plain">(</span><span class="reserved">code_generation</span><span class="plain"> *</span><span class="identifier">gen</span><span class="plain">) {</span>
2019-06-29 15:17:29 +03:00
&lt;<span class="cwebmacro">Phase one - preparation</span> <span class="cwebmacronumber">8.1</span>&gt;<span class="plain">;</span>
&lt;<span class="cwebmacro">Phase two - traverse</span> <span class="cwebmacronumber">8.2</span>&gt;<span class="plain">;</span>
&lt;<span class="cwebmacro">Phase three - consolidation</span> <span class="cwebmacronumber">8.3</span>&gt;<span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function CodeGen::generate is used in <a href="#SP1">&#167;1</a>.</p>
<p class="inwebparagraph"><a id="SP8_1"></a><b>&#167;8.1. </b><code class="display">
&lt;<span class="cwebmacrodefn">Phase one - preparation</span> <span class="cwebmacronumber">8.1</span>&gt; =
</code></p>
<pre class="displaydefn">
2019-03-17 14:40:57 +02:00
<span class="identifier">Inter::Symbols::clear_transient_flags</span><span class="plain">();</span>
2019-06-29 15:17:29 +03:00
<span class="functiontext">CodeGen::FC::prepare</span><span class="plain">(</span><span class="identifier">gen</span><span class="plain">);</span>
<span class="functiontext">CodeGen::CL::prepare</span><span class="plain">(</span><span class="identifier">gen</span><span class="plain">);</span>
<span class="functiontext">CodeGen::Var::prepare</span><span class="plain">(</span><span class="identifier">gen</span><span class="plain">);</span>
<span class="functiontext">CodeGen::IP::prepare</span><span class="plain">(</span><span class="identifier">gen</span><span class="plain">);</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP8">&#167;8</a>.</p>
<p class="inwebparagraph"><a id="SP8_2"></a><b>&#167;8.2. </b><code class="display">
&lt;<span class="cwebmacrodefn">Phase two - traverse</span> <span class="cwebmacronumber">8.2</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="functiontext">CodeGen::FC::iterate</span><span class="plain">(</span><span class="identifier">gen</span><span class="plain">);</span>
2019-06-29 15:17:29 +03:00
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP8">&#167;8</a>.</p>
<p class="inwebparagraph"><a id="SP8_3"></a><b>&#167;8.3. </b><code class="display">
&lt;<span class="cwebmacrodefn">Phase three - consolidation</span> <span class="cwebmacronumber">8.3</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="functiontext">CodeGen::CL::responses</span><span class="plain">(</span><span class="identifier">gen</span><span class="plain">);</span>
<span class="functiontext">CodeGen::IP::write_properties</span><span class="plain">(</span><span class="identifier">gen</span><span class="plain">);</span>
<span class="functiontext">CodeGen::CL::sort_literals</span><span class="plain">(</span><span class="identifier">gen</span><span class="plain">);</span>
2019-06-29 15:17:29 +03:00
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP8">&#167;8</a>.</p>
2019-03-17 14:40:57 +02:00
2019-06-29 15:17:29 +03:00
<p class="inwebparagraph"><a id="SP9"></a><b>&#167;9. Marking. </b>We use a transient flag on symbols, but abstract that here:
</p>
<pre class="display">
2019-06-28 00:56:55 +03:00
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">CodeGen::marked</span><span class="plain">(</span><span class="identifier">inter_symbol</span><span class="plain"> *</span><span class="identifier">symb_name</span><span class="plain">) {</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">Inter::Symbols::get_flag</span><span class="plain">(</span><span class="identifier">symb_name</span><span class="plain">, </span><span class="identifier">TRAVERSE_MARK_BIT</span><span class="plain">);</span>
<span class="plain">}</span>
2019-03-17 14:40:57 +02:00
2019-06-28 00:56:55 +03:00
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">CodeGen::mark</span><span class="plain">(</span><span class="identifier">inter_symbol</span><span class="plain"> *</span><span class="identifier">symb_name</span><span class="plain">) {</span>
<span class="identifier">Inter::Symbols::set_flag</span><span class="plain">(</span><span class="identifier">symb_name</span><span class="plain">, </span><span class="identifier">TRAVERSE_MARK_BIT</span><span class="plain">);</span>
<span class="plain">}</span>
2019-03-17 14:40:57 +02:00
2019-06-28 00:56:55 +03:00
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">CodeGen::unmark</span><span class="plain">(</span><span class="identifier">inter_symbol</span><span class="plain"> *</span><span class="identifier">symb_name</span><span class="plain">) {</span>
<span class="identifier">Inter::Symbols::clear_flag</span><span class="plain">(</span><span class="identifier">symb_name</span><span class="plain">, </span><span class="identifier">TRAVERSE_MARK_BIT</span><span class="plain">);</span>
<span class="plain">}</span>
2019-03-17 14:40:57 +02:00
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function CodeGen::marked is used in 4/iap (<a href="4-iap.html#SP5_8_4">&#167;5.8.4</a>), 5/fi (<a href="5-fi.html#SP1">&#167;1</a>).</p>
2019-03-17 14:40:57 +02:00
<p class="endnote">The function CodeGen::mark is used in 4/iap (<a href="4-iap.html#SP5_8_4">&#167;5.8.4</a>), 5/fi (<a href="5-fi.html#SP1">&#167;1</a>).</p>
2019-03-17 14:40:57 +02:00
<p class="endnote">The function CodeGen::unmark is used in 4/iap (<a href="4-iap.html#SP5_8">&#167;5.8</a>), 5/fi (<a href="5-fi.html#SP1">&#167;1</a>).</p>
2019-03-17 14:40:57 +02:00
<hr class="tocbar">
<ul class="toc"><li><i>(This section begins Chapter 4: Inter to Final Code.)</i></li><li><a href="4-fc.html">Continue with 'Frame Control'</a></li></ul><hr class="tocbar">
2019-04-22 17:42:10 +03:00
<!--End of weave-->
2019-03-17 14:40:57 +02:00
</body>
</html>