986 lines
206 KiB
HTML
986 lines
206 KiB
HTML
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
|
<html>
|
|
<head>
|
|
<title>Preprocessor</title>
|
|
<link href="../docs-assets/Breadcrumbs.css" rel="stylesheet" rev="stylesheet" type="text/css">
|
|
<meta name="viewport" content="width=device-width initial-scale=1">
|
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
|
<meta http-equiv="Content-Language" content="en-gb">
|
|
|
|
<link href="../docs-assets/Contents.css" rel="stylesheet" rev="stylesheet" type="text/css">
|
|
<link href="../docs-assets/Progress.css" rel="stylesheet" rev="stylesheet" type="text/css">
|
|
<link href="../docs-assets/Navigation.css" rel="stylesheet" rev="stylesheet" type="text/css">
|
|
<link href="../docs-assets/Fonts.css" rel="stylesheet" rev="stylesheet" type="text/css">
|
|
<link href="../docs-assets/Base.css" rel="stylesheet" rev="stylesheet" type="text/css">
|
|
<script>
|
|
function togglePopup(material_id) {
|
|
var popup = document.getElementById(material_id);
|
|
popup.classList.toggle("show");
|
|
}
|
|
</script>
|
|
|
|
<link href="../docs-assets/Popups.css" rel="stylesheet" rev="stylesheet" type="text/css">
|
|
<link href="../docs-assets/Colours.css" rel="stylesheet" rev="stylesheet" type="text/css">
|
|
|
|
</head>
|
|
<body class="commentary-font">
|
|
<nav role="navigation">
|
|
<h1><a href="../index.html">
|
|
<img src="../docs-assets/Octagram.png" width=72 height=72">
|
|
</a></h1>
|
|
<ul><li><a href="../inweb/index.html">inweb</a></li>
|
|
</ul><h2>Foundation Module</h2><ul>
|
|
<li><a href="index.html"><span class="selectedlink">foundation</span></a></li>
|
|
<li><a href="../foundation-test/index.html">foundation-test</a></li>
|
|
</ul><h2>Example Webs</h2><ul>
|
|
<li><a href="../goldbach/index.html">goldbach</a></li>
|
|
<li><a href="../twinprimes/twinprimes.html">twinprimes</a></li>
|
|
<li><a href="../eastertide/index.html">eastertide</a></li>
|
|
</ul><h2>Repository</h2><ul>
|
|
<li><a href="https://github.com/ganelson/inweb"><img src="../docs-assets/github.png" height=18> github</a></li>
|
|
</ul><h2>Related Projects</h2><ul>
|
|
<li><a href="../../../inform/docs/overview.html">inform</a></li>
|
|
<li><a href="../../../intest/docs/index.html">intest</a></li>
|
|
|
|
</ul>
|
|
</nav>
|
|
<main role="main">
|
|
<!--Weave of 'Preprocessor' generated by Inweb-->
|
|
<div class="breadcrumbs">
|
|
<ul class="crumbs"><li><a href="../index.html">Home</a></li><li><a href="index.html">foundation</a></li><li><a href="index.html#4">Chapter 4: Text Handling</a></li><li><b>Preprocessor</b></li></ul></div>
|
|
<p class="purpose">A simple, general-purpose preprocessor for text files, expanding macros and performing repetitions.</p>
|
|
|
|
<ul class="toc"><li><a href="4-prp.html#SP1">§1. Scanner</a></li><li><a href="4-prp.html#SP5">§5. Variables</a></li><li><a href="4-prp.html#SP9">§9. Macros</a></li><li><a href="4-prp.html#SP13">§13. Reserved macros</a></li><li><a href="4-prp.html#SP15">§15. The expander for user-defined macros</a></li><li><a href="4-prp.html#SP16">§16. The set expander</a></li><li><a href="4-prp.html#SP17">§17. The repeat expander</a></li><li><a href="4-prp.html#SP18">§18. The expander used for all loop ends</a></li></ul><hr class="tocbar">
|
|
|
|
<p class="commentary firstcommentary"><a id="SP1" class="paragraph-anchor"></a><b>§1. Scanner. </b>Writing a general-purpose preprocessor really is coding like it's 1974, but
|
|
it turns out to be useful for multiple applications in the Inform project, and
|
|
saves us having to have dependencies on behemoths like the mighty <span class="extract"><span class="extract-syntax">m4</span></span>.
|
|
</p>
|
|
|
|
<p class="commentary">For documentation on the markup notation, see <a href="../inweb/M-wtaw.html" class="internal">Webs, Tangling and Weaving (in inweb)</a>.
|
|
</p>
|
|
|
|
<p class="commentary">To use the preprocessor, call:
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="function-syntax">Preprocessor::preprocess</span><span class="plain-syntax">(</span><span class="identifier-syntax">from</span><span class="plain-syntax">, </span><span class="identifier-syntax">to</span><span class="plain-syntax">, </span><span class="identifier-syntax">header</span><span class="plain-syntax">, </span><span class="identifier-syntax">special_macros</span><span class="plain-syntax">, </span><span class="identifier-syntax">specifics</span><span class="plain-syntax">)</span>
|
|
</pre>
|
|
<p class="commentary">where <span class="extract"><span class="extract-syntax">from</span></span> and <span class="extract"><span class="extract-syntax">to</span></span> are filenames, <span class="extract"><span class="extract-syntax">header</span></span> is text to place at the top of
|
|
the file (if any), <span class="extract"><span class="extract-syntax">special_macros</span></span> is a <span class="extract"><span class="extract-syntax">linked_list</span></span> of <span class="extract"><span class="extract-syntax">preprocessor_macro</span></span>s
|
|
set up with special meanings to the situation, and <span class="extract"><span class="extract-syntax">specifics</span></span> is a general
|
|
pointer to any data those special meanings need to use.
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Preprocessor::preprocess</span><span class="plain-syntax">(</span><span class="reserved-syntax">filename</span><span class="plain-syntax"> *</span><span class="identifier-syntax">prototype</span><span class="plain-syntax">, </span><span class="reserved-syntax">filename</span><span class="plain-syntax"> *</span><span class="identifier-syntax">F</span><span class="plain-syntax">, </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">header</span><span class="plain-syntax">,</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">linked_list</span><span class="plain-syntax"> *</span><span class="identifier-syntax">special_macros</span><span class="plain-syntax">, </span><span class="reserved-syntax">general_pointer</span><span class="plain-syntax"> </span><span class="identifier-syntax">specifics</span><span class="plain-syntax">, </span><span class="identifier-syntax">wchar_t</span><span class="plain-syntax"> </span><span class="identifier-syntax">comment_char</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> </span><span class="identifier-syntax">processed_file</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">STREAM_OPEN_TO_FILE</span><span class="plain-syntax">(&</span><span class="identifier-syntax">processed_file</span><span class="plain-syntax">, </span><span class="identifier-syntax">F</span><span class="plain-syntax">, </span><span class="constant-syntax">ISO_ENC</span><span class="plain-syntax">) == </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> </span><a href="3-em.html#SP2" class="function-link"><span class="function-syntax">Errors::fatal_with_file</span></a><span class="plain-syntax">(</span><span class="string-syntax">"unable to write tangled file"</span><span class="plain-syntax">, </span><span class="identifier-syntax">F</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">OUT</span><span class="plain-syntax"> = &</span><span class="identifier-syntax">processed_file</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"%S"</span><span class="plain-syntax">, </span><span class="identifier-syntax">header</span><span class="plain-syntax">);</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">preprocessor_state</span><span class="plain-syntax"> </span><span class="identifier-syntax">PPS</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-prp.html#SP1_2" class="named-paragraph-link"><span class="named-paragraph">Initialise the preprocessor state</span><span class="named-paragraph-number">1.2</span></a></span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><a href="4-tf.html#SP5" class="function-link"><span class="function-syntax">TextFiles::read</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">prototype</span><span class="plain-syntax">, </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">, </span><span class="string-syntax">"can't open prototype file"</span><span class="plain-syntax">,</span>
|
|
<span class="plain-syntax"> </span><span class="constant-syntax">TRUE</span><span class="plain-syntax">, </span><a href="4-prp.html#SP3" class="function-link"><span class="function-syntax">Preprocessor::scan_line</span></a><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, &</span><span class="identifier-syntax">PPS</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">STREAM_CLOSE</span><span class="plain-syntax">(</span><span class="identifier-syntax">OUT</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax">}</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP1_1" class="paragraph-anchor"></a><b>§1.1. </b>The following imposing-looking set of state data is used as we work through
|
|
the prototype file line-by-line:
|
|
</p>
|
|
|
|
<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="constant-syntax">MAX_PREPROCESSOR_LOOP_DEPTH</span><span class="plain-syntax"> </span><span class="constant-syntax">8</span>
|
|
</pre>
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="reserved-syntax">typedef</span><span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">preprocessor_state</span><span class="plain-syntax"> {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">dest</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">preprocessor_macro</span><span class="plain-syntax"> *</span><span class="identifier-syntax">defining</span><span class="plain-syntax">; </span><span class="comment-syntax"> a "define" body being scanned</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">repeat_sp</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">shadow_sp</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">preprocessor_loop</span><span class="plain-syntax"> </span><span class="identifier-syntax">repeat_data</span><span class="plain-syntax">[</span><span class="constant-syntax">MAX_PREPROCESSOR_LOOP_DEPTH</span><span class="plain-syntax">];</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">suppress_newline</span><span class="plain-syntax">; </span><span class="comment-syntax"> at the end of this line</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">last_line_was_blank</span><span class="plain-syntax">; </span><span class="comment-syntax"> used to suppress runs of multiple blank lines</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">preprocessor_variable_set</span><span class="plain-syntax"> *</span><span class="identifier-syntax">global_variables</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">preprocessor_variable_set</span><span class="plain-syntax"> *</span><span class="identifier-syntax">stack_frame</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">linked_list</span><span class="plain-syntax"> *</span><span class="identifier-syntax">known_macros</span><span class="plain-syntax">; </span><span class="comment-syntax"> of </span><span class="extract"><span class="extract-syntax">preprocessor_macro</span></span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">general_pointer</span><span class="plain-syntax"> </span><span class="identifier-syntax">specifics</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">wchar_t</span><span class="plain-syntax"> </span><span class="identifier-syntax">comment_character</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax">} </span><span class="reserved-syntax">preprocessor_state</span><span class="plain-syntax">;</span>
|
|
|
|
<span class="reserved-syntax">typedef</span><span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">preprocessor_loop</span><span class="plain-syntax"> {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">loop_var_name</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">linked_list</span><span class="plain-syntax"> *</span><span class="identifier-syntax">iterations</span><span class="plain-syntax">; </span><span class="comment-syntax"> of </span><span class="extract"><span class="extract-syntax">text_stream</span></span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">repeat_is_block</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">repeat_saved_dest</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax">} </span><span class="reserved-syntax">preprocessor_loop</span><span class="plain-syntax">;</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>The structure preprocessor_state is private to this section.</li><li>The structure preprocessor_loop is private to this section.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP1_2" class="paragraph-anchor"></a><b>§1.2. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Initialise the preprocessor state</span><span class="named-paragraph-number">1.2</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">PPS</span><span class="plain-syntax">.</span><span class="element-syntax">dest</span><span class="plain-syntax"> = </span><span class="identifier-syntax">OUT</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">PPS</span><span class="plain-syntax">.</span><span class="element-syntax">suppress_newline</span><span class="plain-syntax"> = </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">PPS</span><span class="plain-syntax">.</span><span class="element-syntax">last_line_was_blank</span><span class="plain-syntax"> = </span><span class="constant-syntax">TRUE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">PPS</span><span class="plain-syntax">.</span><span class="element-syntax">defining</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">PPS</span><span class="plain-syntax">.</span><span class="element-syntax">repeat_sp</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">PPS</span><span class="plain-syntax">.</span><span class="element-syntax">shadow_sp</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">PPS</span><span class="plain-syntax">.</span><span class="element-syntax">global_variables</span><span class="plain-syntax"> = </span><a href="4-prp.html#SP7" class="function-link"><span class="function-syntax">Preprocessor::new_variable_set</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">NULL</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">PPS</span><span class="plain-syntax">.</span><span class="element-syntax">stack_frame</span><span class="plain-syntax"> = </span><span class="identifier-syntax">PPS</span><span class="plain-syntax">.</span><span class="element-syntax">global_variables</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">PPS</span><span class="plain-syntax">.</span><span class="element-syntax">known_macros</span><span class="plain-syntax"> = </span><a href="4-prp.html#SP13" class="function-link"><span class="function-syntax">Preprocessor::list_of_reserved_macros</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">special_macros</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">PPS</span><span class="plain-syntax">.</span><span class="element-syntax">specifics</span><span class="plain-syntax"> = </span><span class="identifier-syntax">specifics</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">PPS</span><span class="plain-syntax">.</span><span class="element-syntax">comment_character</span><span class="plain-syntax"> = </span><span class="identifier-syntax">comment_char</span><span class="plain-syntax">;</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="4-prp.html#SP1">§1</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP2" class="paragraph-anchor"></a><b>§2. </b>Conceptually, each loop runs a variable with a given name through a series
|
|
of textual values in sequence, and we store that data here:
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Preprocessor::set_loop_var_name</span><button class="popup" onclick="togglePopup('usagePopup1')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup1">Usage of <span class="code-font"><span class="function-syntax">Preprocessor::set_loop_var_name</span></span>:<br/><a href="4-prp.html#SP4_1_3_1_3">§4.1.3.1.3</a>, <a href="4-prp.html#SP17">§17</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">preprocessor_loop</span><span class="plain-syntax"> *</span><span class="identifier-syntax">loop</span><span class="plain-syntax">, </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">name</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">loop</span><span class="plain-syntax">-></span><span class="identifier-syntax">loop_var_name</span><span class="plain-syntax"> = </span><a href="4-sm.html#SP3" class="function-link"><span class="function-syntax">Str::duplicate</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">name</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax">}</span>
|
|
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Preprocessor::add_loop_iteration</span><button class="popup" onclick="togglePopup('usagePopup2')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup2">Usage of <span class="code-font"><span class="function-syntax">Preprocessor::add_loop_iteration</span></span>:<br/><a href="4-prp.html#SP17">§17</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">preprocessor_loop</span><span class="plain-syntax"> *</span><span class="identifier-syntax">loop</span><span class="plain-syntax">, </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">value</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">ADD_TO_LINKED_LIST</span><span class="plain-syntax">(</span><a href="4-sm.html#SP3" class="function-link"><span class="function-syntax">Str::duplicate</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">value</span><span class="plain-syntax">), </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax">, </span><span class="identifier-syntax">loop</span><span class="plain-syntax">-></span><span class="element-syntax">iterations</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax">}</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP3" class="paragraph-anchor"></a><b>§3. </b>Lines from the prototype (or sometimes from files spliced in) are read, one
|
|
at a time, by the following.
|
|
</p>
|
|
|
|
<p class="commentary">Note that <span class="extract"><span class="extract-syntax">define</span></span> and <span class="extract"><span class="extract-syntax">end-define</span></span> are not themselves macros, and are handled
|
|
directly here. So you cannot use repeat loops to define multiple macros with
|
|
parametrised names: but then, nor should you.
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Preprocessor::scan_line</span><button class="popup" onclick="togglePopup('usagePopup3')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup3">Usage of <span class="code-font"><span class="function-syntax">Preprocessor::scan_line</span></span>:<br/><a href="4-prp.html#SP1">§1</a>, <a href="4-prp.html#SP15">§15</a>, <a href="4-prp.html#SP18_1">§18.1</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">line</span><span class="plain-syntax">, </span><span class="reserved-syntax">text_file_position</span><span class="plain-syntax"> *</span><span class="identifier-syntax">tfp</span><span class="plain-syntax">, </span><span class="reserved-syntax">void</span><span class="plain-syntax"> *</span><span class="identifier-syntax">X</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">preprocessor_state</span><span class="plain-syntax"> *</span><span class="identifier-syntax">PPS</span><span class="plain-syntax"> = (</span><span class="reserved-syntax">preprocessor_state</span><span class="plain-syntax"> *) </span><span class="identifier-syntax">X</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-prp.html#SP3_1" class="named-paragraph-link"><span class="named-paragraph">Skip comments</span><span class="named-paragraph-number">3.1</span></a></span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-prp.html#SP3_2" class="named-paragraph-link"><span class="named-paragraph">Deal with textual definitions of new macros</span><span class="named-paragraph-number">3.2</span></a></span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><a href="4-prp.html#SP4" class="function-link"><span class="function-syntax">Preprocessor::expand</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">line</span><span class="plain-syntax">, </span><span class="identifier-syntax">tfp</span><span class="plain-syntax">, </span><span class="identifier-syntax">PPS</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-prp.html#SP3_3" class="named-paragraph-link"><span class="named-paragraph">Sometimes, but only sometimes, output a newline</span><span class="named-paragraph-number">3.3</span></a></span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax">}</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP3_1" class="paragraph-anchor"></a><b>§3.1. </b>A line is a comment to the preprocessor if its first non-whitespace character
|
|
is the special comment character: often <span class="extract"><span class="extract-syntax">#</span></span>, but not necessarily.
|
|
</p>
|
|
|
|
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Skip comments</span><span class="named-paragraph-number">3.1</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_THROUGH_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">pos</span><span class="plain-syntax">, </span><span class="identifier-syntax">line</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">wchar_t</span><span class="plain-syntax"> </span><span class="identifier-syntax">c</span><span class="plain-syntax"> = </span><a href="4-sm.html#SP13" class="function-link"><span class="function-syntax">Str::get</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pos</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">c</span><span class="plain-syntax"> == </span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-></span><span class="element-syntax">comment_character</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="4-chr.html#SP2" class="function-link"><span class="function-syntax">Characters::is_whitespace</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">c</span><span class="plain-syntax">) == </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">) </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> }</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="4-prp.html#SP3">§3</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP3_2" class="paragraph-anchor"></a><b>§3.2. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Deal with textual definitions of new macros</span><span class="named-paragraph-number">3.2</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">match_results</span><span class="plain-syntax"> </span><span class="identifier-syntax">mr</span><span class="plain-syntax"> = </span><a href="4-pm.html#SP9" class="function-link"><span class="function-syntax">Regexp::create_mr</span></a><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="4-pm.html#SP10" class="function-link"><span class="function-syntax">Regexp::match</span></a><span class="plain-syntax">(&</span><span class="identifier-syntax">mr</span><span class="plain-syntax">, </span><span class="identifier-syntax">line</span><span class="plain-syntax">, </span><span class="identifier-syntax">L</span><span class="string-syntax">" *{define: *(%C+) *} *"</span><span class="plain-syntax">)) </span><span class="named-paragraph-container code-font"><a href="4-prp.html#SP3_2_1" class="named-paragraph-link"><span class="named-paragraph">Begin a bare definition</span><span class="named-paragraph-number">3.2.1</span></a></span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="4-pm.html#SP10" class="function-link"><span class="function-syntax">Regexp::match</span></a><span class="plain-syntax">(&</span><span class="identifier-syntax">mr</span><span class="plain-syntax">, </span><span class="identifier-syntax">line</span><span class="plain-syntax">, </span><span class="identifier-syntax">L</span><span class="string-syntax">" *{define: *(%C+) (%c*)} *"</span><span class="plain-syntax">)) </span><span class="named-paragraph-container code-font"><a href="4-prp.html#SP3_2_2" class="named-paragraph-link"><span class="named-paragraph">Begin a definition</span><span class="named-paragraph-number">3.2.2</span></a></span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="4-pm.html#SP10" class="function-link"><span class="function-syntax">Regexp::match</span></a><span class="plain-syntax">(&</span><span class="identifier-syntax">mr</span><span class="plain-syntax">, </span><span class="identifier-syntax">line</span><span class="plain-syntax">, </span><span class="identifier-syntax">L</span><span class="string-syntax">" *{end-define} *"</span><span class="plain-syntax">)) </span><span class="named-paragraph-container code-font"><a href="4-prp.html#SP3_2_4" class="named-paragraph-link"><span class="named-paragraph">End a definition</span><span class="named-paragraph-number">3.2.4</span></a></span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-></span><span class="element-syntax">defining</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="4-prp.html#SP3_2_3" class="named-paragraph-link"><span class="named-paragraph">Continue a definition</span><span class="named-paragraph-number">3.2.3</span></a></span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><a href="4-pm.html#SP9" class="function-link"><span class="function-syntax">Regexp::dispose_of</span></a><span class="plain-syntax">(&</span><span class="identifier-syntax">mr</span><span class="plain-syntax">);</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="4-prp.html#SP3">§3</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP3_2_1" class="paragraph-anchor"></a><b>§3.2.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Begin a bare definition</span><span class="named-paragraph-number">3.2.1</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-></span><span class="element-syntax">defining</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> </span><a href="3-em.html#SP5" class="function-link"><span class="function-syntax">Errors::in_text_file</span></a><span class="plain-syntax">(</span><span class="string-syntax">"nested definitions are not allowed"</span><span class="plain-syntax">, </span><span class="identifier-syntax">tfp</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">name</span><span class="plain-syntax"> = </span><span class="identifier-syntax">mr</span><span class="plain-syntax">.</span><span class="element-syntax">exp</span><span class="plain-syntax">[0];</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">parameter_specification</span><span class="plain-syntax"> = </span><a href="4-sm.html#SP2" class="function-link"><span class="function-syntax">Str::new</span></a><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-></span><span class="element-syntax">defining</span><span class="plain-syntax"> = </span><a href="4-prp.html#SP11" class="function-link"><span class="function-syntax">Preprocessor::new_macro</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-></span><span class="element-syntax">known_macros</span><span class="plain-syntax">, </span><span class="identifier-syntax">name</span><span class="plain-syntax">,</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">parameter_specification</span><span class="plain-syntax">, </span><a href="4-prp.html#SP15" class="function-link"><span class="function-syntax">Preprocessor::default_expander</span></a><span class="plain-syntax">, </span><span class="identifier-syntax">tfp</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><a href="4-pm.html#SP9" class="function-link"><span class="function-syntax">Regexp::dispose_of</span></a><span class="plain-syntax">(&</span><span class="identifier-syntax">mr</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="4-prp.html#SP3_2">§3.2</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP3_2_2" class="paragraph-anchor"></a><b>§3.2.2. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Begin a definition</span><span class="named-paragraph-number">3.2.2</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-></span><span class="element-syntax">defining</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> </span><a href="3-em.html#SP5" class="function-link"><span class="function-syntax">Errors::in_text_file</span></a><span class="plain-syntax">(</span><span class="string-syntax">"nested definitions are not allowed"</span><span class="plain-syntax">, </span><span class="identifier-syntax">tfp</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">name</span><span class="plain-syntax"> = </span><span class="identifier-syntax">mr</span><span class="plain-syntax">.</span><span class="element-syntax">exp</span><span class="plain-syntax">[0];</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">parameter_specification</span><span class="plain-syntax"> = </span><span class="identifier-syntax">mr</span><span class="plain-syntax">.</span><span class="element-syntax">exp</span><span class="plain-syntax">[1];</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-></span><span class="element-syntax">defining</span><span class="plain-syntax"> = </span><a href="4-prp.html#SP11" class="function-link"><span class="function-syntax">Preprocessor::new_macro</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-></span><span class="element-syntax">known_macros</span><span class="plain-syntax">, </span><span class="identifier-syntax">name</span><span class="plain-syntax">,</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">parameter_specification</span><span class="plain-syntax">, </span><a href="4-prp.html#SP15" class="function-link"><span class="function-syntax">Preprocessor::default_expander</span></a><span class="plain-syntax">, </span><span class="identifier-syntax">tfp</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><a href="4-pm.html#SP9" class="function-link"><span class="function-syntax">Regexp::dispose_of</span></a><span class="plain-syntax">(&</span><span class="identifier-syntax">mr</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="4-prp.html#SP3_2">§3.2</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP3_2_3" class="paragraph-anchor"></a><b>§3.2.3. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Continue a definition</span><span class="named-paragraph-number">3.2.3</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><a href="4-prp.html#SP12" class="function-link"><span class="function-syntax">Preprocessor::add_line_to_macro</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-></span><span class="element-syntax">defining</span><span class="plain-syntax">, </span><span class="identifier-syntax">line</span><span class="plain-syntax">, </span><span class="identifier-syntax">tfp</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><a href="4-pm.html#SP9" class="function-link"><span class="function-syntax">Regexp::dispose_of</span></a><span class="plain-syntax">(&</span><span class="identifier-syntax">mr</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="4-prp.html#SP3_2">§3.2</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP3_2_4" class="paragraph-anchor"></a><b>§3.2.4. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">End a definition</span><span class="named-paragraph-number">3.2.4</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-></span><span class="element-syntax">defining</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> </span><a href="3-em.html#SP5" class="function-link"><span class="function-syntax">Errors::in_text_file</span></a><span class="plain-syntax">(</span><span class="string-syntax">"{end-define} without {define: ...}"</span><span class="plain-syntax">, </span><span class="identifier-syntax">tfp</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-></span><span class="element-syntax">defining</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><a href="4-pm.html#SP9" class="function-link"><span class="function-syntax">Regexp::dispose_of</span></a><span class="plain-syntax">(&</span><span class="identifier-syntax">mr</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax">;</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="4-prp.html#SP3_2">§3.2</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP3_3" class="paragraph-anchor"></a><b>§3.3. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Sometimes, but only sometimes, output a newline</span><span class="named-paragraph-number">3.3</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-></span><span class="element-syntax">suppress_newline</span><span class="plain-syntax"> == </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">OUT</span><span class="plain-syntax"> = </span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-></span><span class="element-syntax">dest</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="4-sm.html#SP8" class="function-link"><span class="function-syntax">Str::len</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">line</span><span class="plain-syntax">) == </span><span class="constant-syntax">0</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-></span><span class="element-syntax">last_line_was_blank</span><span class="plain-syntax"> == </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">) </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"\n"</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-></span><span class="element-syntax">last_line_was_blank</span><span class="plain-syntax"> = </span><span class="constant-syntax">TRUE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-></span><span class="element-syntax">last_line_was_blank</span><span class="plain-syntax"> = </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE</span><span class="plain-syntax">(</span><span class="string-syntax">"\n"</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-></span><span class="element-syntax">suppress_newline</span><span class="plain-syntax"> = </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">;</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="4-prp.html#SP3">§3</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP4" class="paragraph-anchor"></a><b>§4. </b>The expander works on material fed to it which:
|
|
</p>
|
|
|
|
<ul class="items"><li>(i) Does not contain any newlines;
|
|
</li><li>(ii) Contains braces <span class="extract"><span class="extract-syntax">{ ... }</span></span> used in nested pairs (unless there is a syntax
|
|
error in the prototype, in which case we must complain).
|
|
</li></ul>
|
|
<p class="commentary">The idea is the pass everything straight through except any braced matter,
|
|
which needs special attention.
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Preprocessor::expand</span><button class="popup" onclick="togglePopup('usagePopup4')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup4">Usage of <span class="code-font"><span class="function-syntax">Preprocessor::expand</span></span>:<br/><a href="4-prp.html#SP3">§3</a>, <a href="4-prp.html#SP4_1_2">§4.1.2</a>, <a href="4-prp.html#SP4_1_3">§4.1.3</a>, <a href="4-prp.html#SP4_1_3_1_1">§4.1.3.1.1</a>, <a href="4-prp.html#SP18_1">§18.1</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">text</span><span class="plain-syntax">, </span><span class="reserved-syntax">text_file_position</span><span class="plain-syntax"> *</span><span class="identifier-syntax">tfp</span><span class="plain-syntax">, </span><span class="reserved-syntax">preprocessor_state</span><span class="plain-syntax"> *</span><span class="identifier-syntax">PPS</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">TEMPORARY_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">before_matter</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">TEMPORARY_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">braced_matter</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">TEMPORARY_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">after_matter</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">bl</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">, </span><span class="identifier-syntax">after_times</span><span class="plain-syntax"> = </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">; </span><span class="identifier-syntax">i</span><span class="plain-syntax"> < </span><a href="4-sm.html#SP8" class="function-link"><span class="function-syntax">Str::len</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">text</span><span class="plain-syntax">); </span><span class="identifier-syntax">i</span><span class="plain-syntax">++) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">wchar_t</span><span class="plain-syntax"> </span><span class="identifier-syntax">c</span><span class="plain-syntax"> = </span><a href="4-sm.html#SP13" class="function-link"><span class="function-syntax">Str::get_at</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">text</span><span class="plain-syntax">, </span><span class="identifier-syntax">i</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">after_times</span><span class="plain-syntax">) </span><span class="identifier-syntax">PUT_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">after_matter</span><span class="plain-syntax">, </span><span class="identifier-syntax">c</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">c</span><span class="plain-syntax"> == </span><span class="character-syntax">'{'</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">bl</span><span class="plain-syntax">++;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">bl</span><span class="plain-syntax"> > </span><span class="constant-syntax">1</span><span class="plain-syntax">) </span><span class="identifier-syntax">PUT_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">braced_matter</span><span class="plain-syntax">, </span><span class="identifier-syntax">c</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">c</span><span class="plain-syntax"> == </span><span class="character-syntax">'}'</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">bl</span><span class="plain-syntax">--;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">bl</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="identifier-syntax">after_times</span><span class="plain-syntax"> = </span><span class="constant-syntax">TRUE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="identifier-syntax">PUT_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">braced_matter</span><span class="plain-syntax">, </span><span class="identifier-syntax">c</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">bl</span><span class="plain-syntax"> < </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><a href="3-em.html#SP5" class="function-link"><span class="function-syntax">Errors::in_text_file</span></a><span class="plain-syntax">(</span><span class="string-syntax">"too many '}'s"</span><span class="plain-syntax">, </span><span class="identifier-syntax">tfp</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">bl</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="identifier-syntax">PUT_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">before_matter</span><span class="plain-syntax">, </span><span class="identifier-syntax">c</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="identifier-syntax">PUT_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">braced_matter</span><span class="plain-syntax">, </span><span class="identifier-syntax">c</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">bl</span><span class="plain-syntax"> > </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><a href="3-em.html#SP5" class="function-link"><span class="function-syntax">Errors::in_text_file</span></a><span class="plain-syntax">(</span><span class="string-syntax">"too many '{'s"</span><span class="plain-syntax">, </span><span class="identifier-syntax">tfp</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">after_times</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-prp.html#SP4_1" class="named-paragraph-link"><span class="named-paragraph">Expand braced matter</span><span class="named-paragraph-number">4.1</span></a></span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-></span><span class="element-syntax">dest</span><span class="plain-syntax">, </span><span class="string-syntax">"%S"</span><span class="plain-syntax">, </span><span class="identifier-syntax">text</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">before_matter</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">braced_matter</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">after_matter</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax">}</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP4_1" class="paragraph-anchor"></a><b>§4.1. </b>Suppose we are expanding the text <span class="extract"><span class="extract-syntax">this {ADJECTIVE} ocean {BEHAVIOUR}</span></span>: then
|
|
the <span class="extract"><span class="extract-syntax">before_matter</span></span> will be <span class="extract"><span class="extract-syntax">this </span></span>, the <span class="extract"><span class="extract-syntax">braced_matter</span></span> will be <span class="extract"><span class="extract-syntax">ADJECTIVE</span></span>,
|
|
and the <span class="extract"><span class="extract-syntax">after_matter</span></span> will be <span class="extract"><span class="extract-syntax"> ocean {BEHAVIOUR}</span></span>.
|
|
</p>
|
|
|
|
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Expand braced matter</span><span class="named-paragraph-number">4.1</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="4-prp.html#SP5" class="function-link"><span class="function-syntax">Preprocessor::acceptable_variable_name</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">braced_matter</span><span class="plain-syntax">)) {</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-prp.html#SP4_1_2" class="named-paragraph-link"><span class="named-paragraph">Expand a variable name</span><span class="named-paragraph-number">4.1.2</span></a></span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">identifier</span><span class="plain-syntax"> = </span><span class="identifier-syntax">braced_matter</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">parameter_settings</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">match_results</span><span class="plain-syntax"> </span><span class="identifier-syntax">mr</span><span class="plain-syntax"> = </span><a href="4-pm.html#SP9" class="function-link"><span class="function-syntax">Regexp::create_mr</span></a><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="4-pm.html#SP10" class="function-link"><span class="function-syntax">Regexp::match</span></a><span class="plain-syntax">(&</span><span class="identifier-syntax">mr</span><span class="plain-syntax">, </span><span class="identifier-syntax">identifier</span><span class="plain-syntax">, </span><span class="identifier-syntax">L</span><span class="string-syntax">"(%C+) (%c*)"</span><span class="plain-syntax">)) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">identifier</span><span class="plain-syntax"> = </span><span class="identifier-syntax">mr</span><span class="plain-syntax">.</span><span class="element-syntax">exp</span><span class="plain-syntax">[0];</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">parameter_settings</span><span class="plain-syntax"> = </span><span class="identifier-syntax">mr</span><span class="plain-syntax">.</span><span class="element-syntax">exp</span><span class="plain-syntax">[1];</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-prp.html#SP4_1_1" class="named-paragraph-link"><span class="named-paragraph">Work out which macro identifier is meant by a loop name</span><span class="named-paragraph-number">4.1.1</span></a></span><span class="plain-syntax">;</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">preprocessor_macro</span><span class="plain-syntax"> *</span><span class="identifier-syntax">mm</span><span class="plain-syntax"> = </span><a href="4-prp.html#SP14" class="function-link"><span class="function-syntax">Preprocessor::find_macro</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-></span><span class="element-syntax">known_macros</span><span class="plain-syntax">, </span><span class="identifier-syntax">identifier</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">mm</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">TEMPORARY_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">erm</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">erm</span><span class="plain-syntax">, </span><span class="string-syntax">"unknown macro '%S'"</span><span class="plain-syntax">, </span><span class="identifier-syntax">identifier</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><a href="3-em.html#SP5" class="function-link"><span class="function-syntax">Errors::in_text_file_S</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">erm</span><span class="plain-syntax">, </span><span class="identifier-syntax">tfp</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">erm</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-prp.html#SP4_1_3" class="named-paragraph-link"><span class="named-paragraph">Expand a macro</span><span class="named-paragraph-number">4.1.3</span></a></span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><a href="4-pm.html#SP9" class="function-link"><span class="function-syntax">Regexp::dispose_of</span></a><span class="plain-syntax">(&</span><span class="identifier-syntax">mr</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> }</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="4-prp.html#SP4">§4</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP4_1_1" class="paragraph-anchor"></a><b>§4.1.1. </b>So, for example, the identifier <span class="extract"><span class="extract-syntax">repeat</span></span> would be changed here either to
|
|
<span class="extract"><span class="extract-syntax">repeat-block</span></span> or <span class="extract"><span class="extract-syntax">repeat-span</span></span>: see above for an explanation.
|
|
</p>
|
|
|
|
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Work out which macro identifier is meant by a loop name</span><span class="named-paragraph-number">4.1.1</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">preprocessor_macro</span><span class="plain-syntax"> *</span><span class="identifier-syntax">loop_mm</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_LINKED_LIST</span><span class="plain-syntax">(</span><span class="identifier-syntax">loop_mm</span><span class="plain-syntax">, </span><span class="reserved-syntax">preprocessor_macro</span><span class="plain-syntax">, </span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-></span><span class="element-syntax">known_macros</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="4-sm.html#SP8" class="function-link"><span class="function-syntax">Str::len</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">loop_mm</span><span class="plain-syntax">-></span><span class="element-syntax">loop_name</span><span class="plain-syntax">) > </span><span class="constant-syntax">0</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="4-sm.html#SP19" class="function-link"><span class="function-syntax">Str::eq</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">identifier</span><span class="plain-syntax">, </span><span class="identifier-syntax">loop_mm</span><span class="plain-syntax">-></span><span class="element-syntax">loop_name</span><span class="plain-syntax">)) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="4-sm.html#SP23" class="function-link"><span class="function-syntax">Str::is_whitespace</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">after_matter</span><span class="plain-syntax">)) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">loop_mm</span><span class="plain-syntax">-></span><span class="element-syntax">span</span><span class="plain-syntax"> == </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">) && (</span><span class="identifier-syntax">loop_mm</span><span class="plain-syntax">-></span><span class="element-syntax">begins_loop</span><span class="plain-syntax">))</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">identifier</span><span class="plain-syntax"> = </span><span class="identifier-syntax">loop_mm</span><span class="plain-syntax">-></span><span class="element-syntax">identifier</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">loop_mm</span><span class="plain-syntax">-></span><span class="element-syntax">span</span><span class="plain-syntax">) && (</span><span class="identifier-syntax">loop_mm</span><span class="plain-syntax">-></span><span class="element-syntax">begins_loop</span><span class="plain-syntax">))</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">identifier</span><span class="plain-syntax"> = </span><span class="identifier-syntax">loop_mm</span><span class="plain-syntax">-></span><span class="element-syntax">identifier</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">TEMPORARY_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">end_name</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">end_name</span><span class="plain-syntax">, </span><span class="string-syntax">"end-%S"</span><span class="plain-syntax">, </span><span class="identifier-syntax">loop_mm</span><span class="plain-syntax">-></span><span class="element-syntax">loop_name</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="4-sm.html#SP19" class="function-link"><span class="function-syntax">Str::eq</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">identifier</span><span class="plain-syntax">, </span><span class="identifier-syntax">end_name</span><span class="plain-syntax">)) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-></span><span class="element-syntax">repeat_sp</span><span class="plain-syntax"> > </span><span class="constant-syntax">0</span><span class="plain-syntax">) &&</span>
|
|
<span class="plain-syntax"> (</span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-></span><span class="element-syntax">repeat_data</span><span class="plain-syntax">[</span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-></span><span class="element-syntax">repeat_sp</span><span class="plain-syntax">-1].</span><span class="element-syntax">repeat_is_block</span><span class="plain-syntax">)) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">loop_mm</span><span class="plain-syntax">-></span><span class="element-syntax">span</span><span class="plain-syntax"> == </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">) && (</span><span class="identifier-syntax">loop_mm</span><span class="plain-syntax">-></span><span class="element-syntax">ends_loop</span><span class="plain-syntax">))</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">identifier</span><span class="plain-syntax"> = </span><span class="identifier-syntax">loop_mm</span><span class="plain-syntax">-></span><span class="element-syntax">identifier</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">loop_mm</span><span class="plain-syntax">-></span><span class="element-syntax">span</span><span class="plain-syntax">) && (</span><span class="identifier-syntax">loop_mm</span><span class="plain-syntax">-></span><span class="element-syntax">ends_loop</span><span class="plain-syntax">))</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">identifier</span><span class="plain-syntax"> = </span><span class="identifier-syntax">loop_mm</span><span class="plain-syntax">-></span><span class="element-syntax">identifier</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">end_name</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> }</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="4-prp.html#SP4_1">§4.1</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP4_1_2" class="paragraph-anchor"></a><b>§4.1.2. </b>Note that if we are inside a loop, we do not perform expansion on the variable
|
|
name, and instead pass it through unchanged — still as, say, <span class="extract"><span class="extract-syntax">{NAME}</span></span>. This
|
|
is because it won't be expanded until later, when the expander reaches the
|
|
end of the loop body.
|
|
</p>
|
|
|
|
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Expand a variable name</span><span class="named-paragraph-number">4.1.2</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><a href="4-prp.html#SP4" class="function-link"><span class="function-syntax">Preprocessor::expand</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">before_matter</span><span class="plain-syntax">, </span><span class="identifier-syntax">tfp</span><span class="plain-syntax">, </span><span class="identifier-syntax">PPS</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-></span><span class="element-syntax">repeat_sp</span><span class="plain-syntax"> > </span><span class="constant-syntax">0</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-></span><span class="element-syntax">dest</span><span class="plain-syntax">, </span><span class="string-syntax">"{%S}"</span><span class="plain-syntax">, </span><span class="identifier-syntax">braced_matter</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-prp.html#SP4_1_2_1" class="named-paragraph-link"><span class="named-paragraph">Definitely expand a variable name</span><span class="named-paragraph-number">4.1.2.1</span></a></span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><a href="4-prp.html#SP4" class="function-link"><span class="function-syntax">Preprocessor::expand</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">after_matter</span><span class="plain-syntax">, </span><span class="identifier-syntax">tfp</span><span class="plain-syntax">, </span><span class="identifier-syntax">PPS</span><span class="plain-syntax">);</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="4-prp.html#SP4_1">§4.1</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP4_1_3" class="paragraph-anchor"></a><b>§4.1.3. </b>Similarly, we don't expand macros inside the body of a loop, except that we
|
|
need to expand the <span class="extract"><span class="extract-syntax">{end-repeat-block}</span></span> (or similar) which closes that loop
|
|
body, so that we can escape back into normal mode. Because loop constructs
|
|
may be nested, we need to react to (but not expand) loop openings, too.
|
|
The "shadow stack pointer" shows how deep we are inside these shadowy,
|
|
not-yet-acted-on, loops.
|
|
</p>
|
|
|
|
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Expand a macro</span><span class="named-paragraph-number">4.1.3</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">mm</span><span class="plain-syntax">-></span><span class="element-syntax">suppress_whitespace_when_expanding</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">while</span><span class="plain-syntax"> (</span><a href="4-chr.html#SP2" class="function-link"><span class="function-syntax">Characters::is_whitespace</span></a><span class="plain-syntax">(</span><a href="4-sm.html#SP13" class="function-link"><span class="function-syntax">Str::get_last_char</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">before_matter</span><span class="plain-syntax">)))</span>
|
|
<span class="plain-syntax"> </span><a href="4-sm.html#SP25" class="function-link"><span class="function-syntax">Str::delete_last_character</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">before_matter</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">while</span><span class="plain-syntax"> (</span><a href="4-chr.html#SP2" class="function-link"><span class="function-syntax">Characters::is_whitespace</span></a><span class="plain-syntax">(</span><a href="4-sm.html#SP13" class="function-link"><span class="function-syntax">Str::get_first_char</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">after_matter</span><span class="plain-syntax">)))</span>
|
|
<span class="plain-syntax"> </span><a href="4-sm.html#SP25" class="function-link"><span class="function-syntax">Str::delete_first_character</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">after_matter</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><a href="4-prp.html#SP4" class="function-link"><span class="function-syntax">Preprocessor::expand</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">before_matter</span><span class="plain-syntax">, </span><span class="identifier-syntax">tfp</span><span class="plain-syntax">, </span><span class="identifier-syntax">PPS</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">divert_if_repeating</span><span class="plain-syntax"> = </span><span class="constant-syntax">TRUE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">mm</span><span class="plain-syntax">) && (</span><span class="identifier-syntax">mm</span><span class="plain-syntax">-></span><span class="element-syntax">begins_loop</span><span class="plain-syntax">)) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-></span><span class="element-syntax">shadow_sp</span><span class="plain-syntax">++;</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">mm</span><span class="plain-syntax">) && (</span><span class="identifier-syntax">mm</span><span class="plain-syntax">-></span><span class="element-syntax">ends_loop</span><span class="plain-syntax">)) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-></span><span class="element-syntax">shadow_sp</span><span class="plain-syntax">--;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-></span><span class="element-syntax">shadow_sp</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="identifier-syntax">divert_if_repeating</span><span class="plain-syntax"> = </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> }</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">divert_if_repeating</span><span class="plain-syntax">) && (</span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-></span><span class="element-syntax">repeat_sp</span><span class="plain-syntax"> > </span><span class="constant-syntax">0</span><span class="plain-syntax">)) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-></span><span class="element-syntax">dest</span><span class="plain-syntax">, </span><span class="string-syntax">"{%S}"</span><span class="plain-syntax">, </span><span class="identifier-syntax">braced_matter</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-prp.html#SP4_1_3_1" class="named-paragraph-link"><span class="named-paragraph">Definitely expand a macro</span><span class="named-paragraph-number">4.1.3.1</span></a></span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">mm</span><span class="plain-syntax">-></span><span class="element-syntax">suppress_newline_after_expanding</span><span class="plain-syntax">) </span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-></span><span class="element-syntax">suppress_newline</span><span class="plain-syntax"> = </span><span class="constant-syntax">TRUE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><a href="4-prp.html#SP4" class="function-link"><span class="function-syntax">Preprocessor::expand</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">after_matter</span><span class="plain-syntax">, </span><span class="identifier-syntax">tfp</span><span class="plain-syntax">, </span><span class="identifier-syntax">PPS</span><span class="plain-syntax">);</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="4-prp.html#SP4_1">§4.1</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP4_1_2_1" class="paragraph-anchor"></a><b>§4.1.2.1. </b>We can now forget about the <span class="extract"><span class="extract-syntax">before_matter</span></span>, the <span class="extract"><span class="extract-syntax">after_matter</span></span>, or whether
|
|
we ought not to expand after all: that's all taken care of. A variable expands
|
|
to its value:
|
|
</p>
|
|
|
|
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Definitely expand a variable name</span><span class="named-paragraph-number">4.1.2.1</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">preprocessor_variable</span><span class="plain-syntax"> *</span><span class="identifier-syntax">var</span><span class="plain-syntax"> =</span>
|
|
<span class="plain-syntax"> </span><a href="4-prp.html#SP7" class="function-link"><span class="function-syntax">Preprocessor::find_variable</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">braced_matter</span><span class="plain-syntax">, </span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-></span><span class="element-syntax">stack_frame</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">var</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-></span><span class="element-syntax">dest</span><span class="plain-syntax">, </span><span class="string-syntax">"%S"</span><span class="plain-syntax">, </span><a href="4-prp.html#SP6" class="function-link"><span class="function-syntax">Preprocessor::read_variable</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">var</span><span class="plain-syntax">));</span>
|
|
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">TEMPORARY_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">erm</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">erm</span><span class="plain-syntax">, </span><span class="string-syntax">"unknown variable '%S'"</span><span class="plain-syntax">, </span><span class="identifier-syntax">braced_matter</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><a href="3-em.html#SP5" class="function-link"><span class="function-syntax">Errors::in_text_file_S</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">erm</span><span class="plain-syntax">, </span><span class="identifier-syntax">tfp</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">erm</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> }</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="4-prp.html#SP4_1_2">§4.1.2</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP4_1_3_1" class="paragraph-anchor"></a><b>§4.1.3.1. </b>This looks fussy, but really it delegates the work by calling a function
|
|
attached to the macro, the <span class="extract"><span class="extract-syntax">expander</span></span>.
|
|
</p>
|
|
|
|
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Definitely expand a macro</span><span class="named-paragraph-number">4.1.3.1</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">parameter_values</span><span class="plain-syntax">[</span><span class="constant-syntax">MAX_PP_MACRO_PARAMETERS</span><span class="plain-syntax">];</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax">=0; </span><span class="identifier-syntax">i</span><span class="plain-syntax"><</span><span class="constant-syntax">MAX_PP_MACRO_PARAMETERS</span><span class="plain-syntax">; </span><span class="identifier-syntax">i</span><span class="plain-syntax">++) </span><span class="identifier-syntax">parameter_values</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">] = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-prp.html#SP4_1_3_1_1" class="named-paragraph-link"><span class="named-paragraph">Parse the parameters supplied</span><span class="named-paragraph-number">4.1.3.1.1</span></a></span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-prp.html#SP4_1_3_1_2" class="named-paragraph-link"><span class="named-paragraph">Check that all compulsory parameters have been supplied</span><span class="named-paragraph-number">4.1.3.1.2</span></a></span><span class="plain-syntax">;</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">preprocessor_loop</span><span class="plain-syntax"> *</span><span class="identifier-syntax">loop</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">mm</span><span class="plain-syntax">-></span><span class="element-syntax">begins_loop</span><span class="plain-syntax">) </span><span class="named-paragraph-container code-font"><a href="4-prp.html#SP4_1_3_1_3" class="named-paragraph-link"><span class="named-paragraph">Initialise repetition data for the loop</span><span class="named-paragraph-number">4.1.3.1.3</span></a></span><span class="plain-syntax">;</span>
|
|
|
|
<span class="plain-syntax"> (*(</span><span class="identifier-syntax">mm</span><span class="plain-syntax">-></span><span class="identifier-syntax">expander</span><span class="plain-syntax">))(</span><span class="identifier-syntax">mm</span><span class="plain-syntax">, </span><span class="identifier-syntax">PPS</span><span class="plain-syntax">, </span><span class="identifier-syntax">parameter_values</span><span class="plain-syntax">, </span><span class="identifier-syntax">loop</span><span class="plain-syntax">, </span><span class="identifier-syntax">tfp</span><span class="plain-syntax">);</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="4-prp.html#SP4_1_3">§4.1.3</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP4_1_3_1_1" class="paragraph-anchor"></a><b>§4.1.3.1.1. </b>Note that textual values of the parameters are themselves expanded before
|
|
use: they might contain variables, or even macros. Parameter names are not.
|
|
So you can have <span class="extract"><span class="extract-syntax">in: {WHATEVER}</span></span> but not <span class="extract"><span class="extract-syntax">{WHATEVER}: this</span></span>.
|
|
</p>
|
|
|
|
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Parse the parameters supplied</span><span class="named-paragraph-number">4.1.3.1.1</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">match_results</span><span class="plain-syntax"> </span><span class="identifier-syntax">mr</span><span class="plain-syntax"> = </span><a href="4-pm.html#SP9" class="function-link"><span class="function-syntax">Regexp::create_mr</span></a><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">while</span><span class="plain-syntax"> (</span><a href="4-pm.html#SP10" class="function-link"><span class="function-syntax">Regexp::match</span></a><span class="plain-syntax">(&</span><span class="identifier-syntax">mr</span><span class="plain-syntax">, </span><span class="identifier-syntax">parameter_settings</span><span class="plain-syntax">, </span><span class="identifier-syntax">L</span><span class="string-syntax">" *(%C+): *(%c*)"</span><span class="plain-syntax">)) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">setting</span><span class="plain-syntax"> = </span><span class="identifier-syntax">mr</span><span class="plain-syntax">.</span><span class="element-syntax">exp</span><span class="plain-syntax">[0];</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">value</span><span class="plain-syntax"> = </span><span class="identifier-syntax">mr</span><span class="plain-syntax">.</span><span class="element-syntax">exp</span><span class="plain-syntax">[1];</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">remainder</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">match_results</span><span class="plain-syntax"> </span><span class="identifier-syntax">mr3</span><span class="plain-syntax"> = </span><a href="4-pm.html#SP9" class="function-link"><span class="function-syntax">Regexp::create_mr</span></a><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="4-pm.html#SP10" class="function-link"><span class="function-syntax">Regexp::match</span></a><span class="plain-syntax">(&</span><span class="identifier-syntax">mr3</span><span class="plain-syntax">, </span><span class="identifier-syntax">value</span><span class="plain-syntax">, </span><span class="identifier-syntax">L</span><span class="string-syntax">"(%c+?) *(%C+: *%c*)"</span><span class="plain-syntax">)) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">value</span><span class="plain-syntax"> = </span><span class="identifier-syntax">mr3</span><span class="plain-syntax">.</span><span class="element-syntax">exp</span><span class="plain-syntax">[0];</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">remainder</span><span class="plain-syntax"> = </span><span class="identifier-syntax">mr3</span><span class="plain-syntax">.</span><span class="element-syntax">exp</span><span class="plain-syntax">[1];</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">found</span><span class="plain-syntax"> = </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax">=0; </span><span class="identifier-syntax">i</span><span class="function-syntax"><mm-></span><span class="element-syntax">no_parameters</span><span class="plain-syntax">; </span><span class="identifier-syntax">i</span><span class="plain-syntax">++)</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="4-sm.html#SP19" class="function-link"><span class="function-syntax">Str::eq</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">setting</span><span class="plain-syntax">, </span><span class="identifier-syntax">mm</span><span class="plain-syntax">-></span><span class="element-syntax">parameters</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">]-></span><span class="element-syntax">name</span><span class="plain-syntax">)) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">found</span><span class="plain-syntax"> = </span><span class="constant-syntax">TRUE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">parameter_values</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">] = </span><a href="4-sm.html#SP2" class="function-link"><span class="function-syntax">Str::new</span></a><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">saved</span><span class="plain-syntax"> = </span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-></span><span class="element-syntax">dest</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-></span><span class="element-syntax">dest</span><span class="plain-syntax"> = </span><span class="identifier-syntax">parameter_values</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">];</span>
|
|
<span class="plain-syntax"> </span><a href="4-prp.html#SP4" class="function-link"><span class="function-syntax">Preprocessor::expand</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">value</span><span class="plain-syntax">, </span><span class="identifier-syntax">tfp</span><span class="plain-syntax">, </span><span class="identifier-syntax">PPS</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-></span><span class="element-syntax">dest</span><span class="plain-syntax"> = </span><span class="identifier-syntax">saved</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">found</span><span class="plain-syntax"> == </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">TEMPORARY_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">erm</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">erm</span><span class="plain-syntax">, </span><span class="string-syntax">"unknown parameter '%S:'"</span><span class="plain-syntax">, </span><span class="identifier-syntax">setting</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><a href="3-em.html#SP5" class="function-link"><span class="function-syntax">Errors::in_text_file_S</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">erm</span><span class="plain-syntax">, </span><span class="identifier-syntax">tfp</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">erm</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><a href="4-sm.html#SP15" class="function-link"><span class="function-syntax">Str::clear</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">parameter_settings</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><a href="4-sm.html#SP17" class="function-link"><span class="function-syntax">Str::copy</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">parameter_settings</span><span class="plain-syntax">, </span><span class="identifier-syntax">remainder</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><a href="4-pm.html#SP9" class="function-link"><span class="function-syntax">Regexp::dispose_of</span></a><span class="plain-syntax">(&</span><span class="identifier-syntax">mr3</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><a href="4-pm.html#SP9" class="function-link"><span class="function-syntax">Regexp::dispose_of</span></a><span class="plain-syntax">(&</span><span class="identifier-syntax">mr</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="4-sm.html#SP23" class="function-link"><span class="function-syntax">Str::is_whitespace</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">parameter_settings</span><span class="plain-syntax">) == </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> </span><a href="3-em.html#SP5" class="function-link"><span class="function-syntax">Errors::in_text_file</span></a><span class="plain-syntax">(</span><span class="string-syntax">"parameter list is malformed"</span><span class="plain-syntax">, </span><span class="identifier-syntax">tfp</span><span class="plain-syntax">);</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="4-prp.html#SP4_1_3_1">§4.1.3.1</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP4_1_3_1_2" class="paragraph-anchor"></a><b>§4.1.3.1.2. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Check that all compulsory parameters have been supplied</span><span class="named-paragraph-number">4.1.3.1.2</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax">=0; </span><span class="identifier-syntax">i</span><span class="function-syntax"><mm-></span><span class="element-syntax">no_parameters</span><span class="plain-syntax">; </span><span class="identifier-syntax">i</span><span class="plain-syntax">++)</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">parameter_values</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">] == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">mm</span><span class="plain-syntax">-></span><span class="element-syntax">parameters</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">]-></span><span class="element-syntax">optional</span><span class="plain-syntax"> == </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">TEMPORARY_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">erm</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">erm</span><span class="plain-syntax">, </span><span class="string-syntax">"compulsory parameter '%S:' not given"</span><span class="plain-syntax">, </span><span class="identifier-syntax">mm</span><span class="plain-syntax">-></span><span class="element-syntax">parameters</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">]-></span><span class="element-syntax">name</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><a href="3-em.html#SP5" class="function-link"><span class="function-syntax">Errors::in_text_file_S</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">erm</span><span class="plain-syntax">, </span><span class="identifier-syntax">tfp</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">erm</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> }</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="4-prp.html#SP4_1_3_1">§4.1.3.1</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP4_1_3_1_3" class="paragraph-anchor"></a><b>§4.1.3.1.3. </b>The following code is a little misleading. At present, <span class="extract"><span class="extract-syntax">PPS->repeat_sp</span></span> is
|
|
always either 0 or 1, no matter how deep loop nesting is: but that's just an
|
|
artefact of the current scanning algorithm, which might some day change.
|
|
</p>
|
|
|
|
<p class="commentary"><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Initialise repetition data for the loop</span><span class="named-paragraph-number">4.1.3.1.3</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-></span><span class="element-syntax">repeat_sp</span><span class="plain-syntax"> >= </span><span class="constant-syntax">MAX_PREPROCESSOR_LOOP_DEPTH</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><a href="3-em.html#SP5" class="function-link"><span class="function-syntax">Errors::in_text_file</span></a><span class="plain-syntax">(</span><span class="string-syntax">"repetition too deep"</span><span class="plain-syntax">, </span><span class="identifier-syntax">tfp</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">loop</span><span class="plain-syntax"> = &(</span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-></span><span class="element-syntax">repeat_data</span><span class="plain-syntax">[</span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-></span><span class="element-syntax">repeat_sp</span><span class="plain-syntax">++]);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-></span><span class="element-syntax">shadow_sp</span><span class="plain-syntax"> = </span><span class="constant-syntax">1</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><a href="4-prp.html#SP2" class="function-link"><span class="function-syntax">Preprocessor::set_loop_var_name</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">loop</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"NAME"</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">loop</span><span class="plain-syntax">-></span><span class="element-syntax">iterations</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NEW_LINKED_LIST</span><span class="plain-syntax">(</span><span class="reserved-syntax">text_stream</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">loop</span><span class="plain-syntax">-></span><span class="element-syntax">repeat_is_block</span><span class="plain-syntax"> = </span><span class="constant-syntax">TRUE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">mm</span><span class="plain-syntax">-></span><span class="element-syntax">span</span><span class="plain-syntax">) </span><span class="identifier-syntax">loop</span><span class="plain-syntax">-></span><span class="element-syntax">repeat_is_block</span><span class="plain-syntax"> = </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">loop</span><span class="plain-syntax">-></span><span class="element-syntax">repeat_saved_dest</span><span class="plain-syntax"> = </span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-></span><span class="element-syntax">dest</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-></span><span class="element-syntax">dest</span><span class="plain-syntax"> = </span><a href="4-sm.html#SP2" class="function-link"><span class="function-syntax">Str::new</span></a><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> }</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="4-prp.html#SP4_1_3_1">§4.1.3.1</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP5" class="paragraph-anchor"></a><b>§5. Variables. </b>Names of variables should conform to:
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">Preprocessor::acceptable_variable_name</span><button class="popup" onclick="togglePopup('usagePopup5')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup5">Usage of <span class="code-font"><span class="function-syntax">Preprocessor::acceptable_variable_name</span></span>:<br/><a href="4-prp.html#SP4_1">§4.1</a>, <a href="4-prp.html#SP16">§16</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">name</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_THROUGH_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">pos</span><span class="plain-syntax">, </span><span class="identifier-syntax">name</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">wchar_t</span><span class="plain-syntax"> </span><span class="identifier-syntax">c</span><span class="plain-syntax"> = </span><a href="4-sm.html#SP13" class="function-link"><span class="function-syntax">Str::get</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pos</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">c</span><span class="plain-syntax"> >= </span><span class="character-syntax">'0'</span><span class="plain-syntax">) && (</span><span class="identifier-syntax">c</span><span class="plain-syntax"> <= </span><span class="character-syntax">'9'</span><span class="plain-syntax">)) </span><span class="reserved-syntax">continue</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">c</span><span class="plain-syntax"> >= </span><span class="character-syntax">'A'</span><span class="plain-syntax">) && (</span><span class="identifier-syntax">c</span><span class="plain-syntax"> <= </span><span class="character-syntax">'Z'</span><span class="plain-syntax">)) </span><span class="reserved-syntax">continue</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">c</span><span class="plain-syntax"> == </span><span class="character-syntax">'_'</span><span class="plain-syntax">) </span><span class="reserved-syntax">continue</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">TRUE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax">}</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP6" class="paragraph-anchor"></a><b>§6. </b>Variables are all textual:
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="reserved-syntax">typedef</span><span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">preprocessor_variable</span><span class="plain-syntax"> {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">name</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">value</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="constant-syntax">CLASS_DEFINITION</span>
|
|
<span class="plain-syntax">} </span><span class="reserved-syntax">preprocessor_variable</span><span class="plain-syntax">;</span>
|
|
|
|
<span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="function-syntax">Preprocessor::read_variable</span><button class="popup" onclick="togglePopup('usagePopup6')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup6">Usage of <span class="code-font"><span class="function-syntax">Preprocessor::read_variable</span></span>:<br/><a href="4-prp.html#SP4_1_2_1">§4.1.2.1</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">preprocessor_variable</span><span class="plain-syntax"> *</span><span class="identifier-syntax">var</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">var</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"no such pp variable"</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">var</span><span class="plain-syntax">-></span><span class="element-syntax">value</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax">}</span>
|
|
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Preprocessor::write_variable</span><button class="popup" onclick="togglePopup('usagePopup7')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup7">Usage of <span class="code-font"><span class="function-syntax">Preprocessor::write_variable</span></span>:<br/><a href="4-prp.html#SP8">§8</a>, <a href="4-prp.html#SP15">§15</a>, <a href="4-prp.html#SP16">§16</a>, <a href="4-prp.html#SP18_1">§18.1</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">preprocessor_variable</span><span class="plain-syntax"> *</span><span class="identifier-syntax">var</span><span class="plain-syntax">, </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">val</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">var</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"no such pp variable"</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">var</span><span class="plain-syntax">-></span><span class="element-syntax">value</span><span class="plain-syntax"> = </span><a href="4-sm.html#SP3" class="function-link"><span class="function-syntax">Str::duplicate</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">val</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax">}</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>The structure preprocessor_variable is accessed in 2/dct, 2/trs, 5/ee, 8/bdfw and here.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP7" class="paragraph-anchor"></a><b>§7. </b>Each variable belongs to a single "set". If <span class="extract"><span class="extract-syntax">EXAMPLE</span></span> has one meaning outside a
|
|
definition and another insider, that's two variables with a common name, not
|
|
one variable belonging to two sets at once.
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="reserved-syntax">typedef</span><span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">preprocessor_variable_set</span><span class="plain-syntax"> {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">linked_list</span><span class="plain-syntax"> *</span><span class="identifier-syntax">variables</span><span class="plain-syntax">; </span><span class="comment-syntax"> of </span><span class="extract"><span class="extract-syntax">preprocessor_variable</span></span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">preprocessor_variable_set</span><span class="plain-syntax"> *</span><span class="identifier-syntax">outer</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="constant-syntax">CLASS_DEFINITION</span>
|
|
<span class="plain-syntax">} </span><span class="reserved-syntax">preprocessor_variable_set</span><span class="plain-syntax">;</span>
|
|
|
|
<span class="reserved-syntax">preprocessor_variable_set</span><span class="plain-syntax"> *</span><span class="function-syntax">Preprocessor::new_variable_set</span><button class="popup" onclick="togglePopup('usagePopup8')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup8">Usage of <span class="code-font"><span class="function-syntax">Preprocessor::new_variable_set</span></span>:<br/><a href="4-prp.html#SP1_2">§1.2</a>, <a href="4-prp.html#SP15">§15</a>, <a href="4-prp.html#SP18">§18</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">preprocessor_variable_set</span><span class="plain-syntax"> *</span><span class="identifier-syntax">outer</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">preprocessor_variable_set</span><span class="plain-syntax"> *</span><span class="identifier-syntax">set</span><span class="plain-syntax"> = </span><span class="identifier-syntax">CREATE</span><span class="plain-syntax">(</span><span class="reserved-syntax">preprocessor_variable_set</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">set</span><span class="plain-syntax">-></span><span class="element-syntax">variables</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NEW_LINKED_LIST</span><span class="plain-syntax">(</span><span class="reserved-syntax">preprocessor_variable</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">set</span><span class="plain-syntax">-></span><span class="element-syntax">outer</span><span class="plain-syntax"> = </span><span class="identifier-syntax">outer</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">set</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax">}</span>
|
|
|
|
<span class="reserved-syntax">preprocessor_variable</span><span class="plain-syntax"> *</span><span class="function-syntax">Preprocessor::find_variable_in_one</span><button class="popup" onclick="togglePopup('usagePopup9')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup9">Usage of <span class="code-font"><span class="function-syntax">Preprocessor::find_variable_in_one</span></span>:<br/><a href="4-prp.html#SP8">§8</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">name</span><span class="plain-syntax">,</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">preprocessor_variable_set</span><span class="plain-syntax"> *</span><span class="identifier-syntax">set</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">set</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">preprocessor_variable</span><span class="plain-syntax"> *</span><span class="identifier-syntax">var</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_LINKED_LIST</span><span class="plain-syntax">(</span><span class="identifier-syntax">var</span><span class="plain-syntax">, </span><span class="reserved-syntax">preprocessor_variable</span><span class="plain-syntax">, </span><span class="identifier-syntax">set</span><span class="plain-syntax">-></span><span class="element-syntax">variables</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="4-sm.html#SP19" class="function-link"><span class="function-syntax">Str::eq</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">name</span><span class="plain-syntax">, </span><span class="identifier-syntax">var</span><span class="plain-syntax">-></span><span class="element-syntax">name</span><span class="plain-syntax">))</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">var</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax">}</span>
|
|
|
|
<span class="reserved-syntax">preprocessor_variable</span><span class="plain-syntax"> *</span><span class="function-syntax">Preprocessor::find_variable</span><button class="popup" onclick="togglePopup('usagePopup10')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup10">Usage of <span class="code-font"><span class="function-syntax">Preprocessor::find_variable</span></span>:<br/><a href="4-prp.html#SP4_1_2_1">§4.1.2.1</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">name</span><span class="plain-syntax">,</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">preprocessor_variable_set</span><span class="plain-syntax"> *</span><span class="identifier-syntax">set</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">while</span><span class="plain-syntax"> (</span><span class="identifier-syntax">set</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">preprocessor_variable</span><span class="plain-syntax"> *</span><span class="identifier-syntax">var</span><span class="plain-syntax"> = </span><a href="4-prp.html#SP7" class="function-link"><span class="function-syntax">Preprocessor::find_variable_in_one</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">name</span><span class="plain-syntax">, </span><span class="identifier-syntax">set</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">var</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">var</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">set</span><span class="plain-syntax"> = </span><span class="identifier-syntax">set</span><span class="plain-syntax">-></span><span class="element-syntax">outer</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax">}</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>The structure preprocessor_variable_set is private to this section.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP8" class="paragraph-anchor"></a><b>§8. </b>This creates a variable if it doesn't already exist in the given set. (If
|
|
it exists in some outer set, that doesn't count.)
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="reserved-syntax">preprocessor_variable</span><span class="plain-syntax"> *</span><span class="function-syntax">Preprocessor::ensure_variable</span><button class="popup" onclick="togglePopup('usagePopup11')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup11">Usage of <span class="code-font"><span class="function-syntax">Preprocessor::ensure_variable</span></span>:<br/><a href="4-prp.html#SP15">§15</a>, <a href="4-prp.html#SP16">§16</a>, <a href="4-prp.html#SP18">§18</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">name</span><span class="plain-syntax">,</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">preprocessor_variable_set</span><span class="plain-syntax"> *</span><span class="identifier-syntax">in_set</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">in_set</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) </span><span class="identifier-syntax">internal_error</span><span class="plain-syntax">(</span><span class="string-syntax">"variable without set"</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">preprocessor_variable</span><span class="plain-syntax"> *</span><span class="identifier-syntax">var</span><span class="plain-syntax"> = </span><a href="4-prp.html#SP7" class="function-link"><span class="function-syntax">Preprocessor::find_variable_in_one</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">name</span><span class="plain-syntax">, </span><span class="identifier-syntax">in_set</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">var</span><span class="plain-syntax"> == </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">var</span><span class="plain-syntax"> = </span><span class="identifier-syntax">CREATE</span><span class="plain-syntax">(</span><span class="reserved-syntax">preprocessor_variable</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">var</span><span class="plain-syntax">-></span><span class="element-syntax">name</span><span class="plain-syntax"> = </span><a href="4-sm.html#SP3" class="function-link"><span class="function-syntax">Str::duplicate</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">name</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><a href="4-prp.html#SP6" class="function-link"><span class="function-syntax">Preprocessor::write_variable</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">var</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">""</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">ADD_TO_LINKED_LIST</span><span class="plain-syntax">(</span><span class="identifier-syntax">var</span><span class="plain-syntax">, </span><span class="reserved-syntax">preprocessor_variable</span><span class="plain-syntax">, </span><span class="identifier-syntax">in_set</span><span class="plain-syntax">-></span><span class="element-syntax">variables</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">var</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax">}</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP9" class="paragraph-anchor"></a><b>§9. Macros. </b>For the most part, each macro seen by users corresponds to a single
|
|
<a href="4-prp.html#SP10" class="internal">preprocessor_macro</a>, but loop constructs are an exception. When the user
|
|
types <span class="extract"><span class="extract-syntax">{repeat ...}</span></span>, this is a reference to <span class="extract"><span class="extract-syntax">repeat-block</span></span> if the body of
|
|
what to repeat occupies multiple lines, but to <span class="extract"><span class="extract-syntax">repeat-span</span></span> if only one.
|
|
</p>
|
|
|
|
<p class="commentary">For example, the first <span class="extract"><span class="extract-syntax">repeat</span></span> loop here uses the macros <span class="extract"><span class="extract-syntax">repeat-block</span></span> and
|
|
<span class="extract"><span class="extract-syntax">end-repeat-block</span></span>, and the second uses <span class="extract"><span class="extract-syntax">repeat-span</span></span> and <span class="extract"><span class="extract-syntax">end-repeat-span</span></span>.
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> {repeat with SEA in Black, Caspian}</span>
|
|
<span class="plain-syntax"> Welcome to the SEA Sea.</span>
|
|
<span class="plain-syntax"> {end-repeat}</span>
|
|
<span class="plain-syntax"> ...</span>
|
|
<span class="plain-syntax"> Seas available:{repeat with SEA in Sargasso, Libyan} {SEA} Sea;{end-repeat}</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP10" class="paragraph-anchor"></a><b>§10. </b>There are (for now, anyway) hard but harmlessly large limits on the number of
|
|
parameters and the length of a macro:
|
|
</p>
|
|
|
|
<pre class="definitions code-font"><span class="definition-keyword">define</span> <span class="constant-syntax">MAX_PP_MACRO_PARAMETERS</span><span class="plain-syntax"> </span><span class="constant-syntax">8</span>
|
|
<span class="definition-keyword">define</span> <span class="constant-syntax">MAX_PP_MACRO_LINES</span><span class="plain-syntax"> </span><span class="constant-syntax">128</span>
|
|
</pre>
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="reserved-syntax">typedef</span><span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">preprocessor_macro</span><span class="plain-syntax"> {</span>
|
|
<span class="plain-syntax"> </span><span class="comment-syntax"> syntax</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">identifier</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">preprocessor_macro_parameter</span><span class="plain-syntax"> *</span><span class="identifier-syntax">parameters</span><span class="plain-syntax">[</span><span class="constant-syntax">MAX_PP_MACRO_PARAMETERS</span><span class="plain-syntax">];</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">no_parameters</span><span class="plain-syntax">;</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="comment-syntax"> meaning</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">lines</span><span class="plain-syntax">[</span><span class="constant-syntax">MAX_PP_MACRO_LINES</span><span class="plain-syntax">];</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">no_lines</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">void</span><span class="plain-syntax"> (*</span><span class="identifier-syntax">expander</span><span class="plain-syntax">)(</span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">preprocessor_macro</span><span class="plain-syntax"> *, </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">preprocessor_state</span><span class="plain-syntax"> *, </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> **, </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">preprocessor_loop</span><span class="plain-syntax"> *, </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">text_file_position</span><span class="plain-syntax"> *);</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="comment-syntax"> loop construct if any</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">begins_loop</span><span class="plain-syntax">; </span><span class="comment-syntax"> </span><span class="extract"><span class="extract-syntax">TRUE</span></span><span class="comment-syntax"> for e.g. </span><span class="extract"><span class="extract-syntax">repeat-block</span></span><span class="comment-syntax"> or </span><span class="extract"><span class="extract-syntax">repeat-span</span></span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">ends_loop</span><span class="plain-syntax">; </span><span class="comment-syntax"> </span><span class="extract"><span class="extract-syntax">TRUE</span></span><span class="comment-syntax"> for e.g. </span><span class="extract"><span class="extract-syntax">end-repeat-block</span></span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">loop_name</span><span class="plain-syntax">; </span><span class="comment-syntax"> e.g. </span><span class="extract"><span class="extract-syntax">repeat</span></span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">span</span><span class="plain-syntax">; </span><span class="comment-syntax"> </span><span class="extract"><span class="extract-syntax">TRUE</span></span><span class="comment-syntax"> for e.g. </span><span class="extract"><span class="extract-syntax">end-repeat-span</span></span><span class="comment-syntax"> or </span><span class="extract"><span class="extract-syntax">repeat-span</span></span>
|
|
|
|
<span class="plain-syntax"> </span><span class="comment-syntax"> textual behaviour</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">suppress_newline_after_expanding</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">suppress_whitespace_when_expanding</span><span class="plain-syntax">;</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="constant-syntax">CLASS_DEFINITION</span>
|
|
<span class="plain-syntax">} </span><span class="reserved-syntax">preprocessor_macro</span><span class="plain-syntax">;</span>
|
|
|
|
<span class="reserved-syntax">typedef</span><span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">preprocessor_macro_parameter</span><span class="plain-syntax"> {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">name</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">struct</span><span class="plain-syntax"> </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">definition_token</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">optional</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="constant-syntax">CLASS_DEFINITION</span>
|
|
<span class="plain-syntax">} </span><span class="reserved-syntax">preprocessor_macro_parameter</span><span class="plain-syntax">;</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>The structure preprocessor_macro is private to this section.</li><li>The structure preprocessor_macro_parameter is accessed in 2/trs and here.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP11" class="paragraph-anchor"></a><b>§11. </b>The following creates a new macro and adds it to the list <span class="extract"><span class="extract-syntax">L</span></span>. By default, it
|
|
has an empty definition (i.e., no lines), but may have a meaning provided by its
|
|
<span class="extract"><span class="extract-syntax">expander</span></span> function regardless. The <span class="extract"><span class="extract-syntax">parameter_specification</span></span> is as in the
|
|
textual declaration: for example, <span class="extract"><span class="extract-syntax">in: IN ?towards: WAY</span></span> would be valid, with
|
|
<span class="extract"><span class="extract-syntax">in</span></span> being compulsory and <span class="extract"><span class="extract-syntax">towards</span></span> optional when the macro is used.
|
|
</p>
|
|
|
|
<p class="commentary">If we expected 10000 macros, a dictionary would be better than a list. But in
|
|
fact we expect more like 10.
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="reserved-syntax">preprocessor_macro</span><span class="plain-syntax"> *</span><span class="function-syntax">Preprocessor::new_macro</span><button class="popup" onclick="togglePopup('usagePopup12')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup12">Usage of <span class="code-font"><span class="function-syntax">Preprocessor::new_macro</span></span>:<br/><a href="4-prp.html#SP3_2_1">§3.2.1</a>, <a href="4-prp.html#SP3_2_2">§3.2.2</a>, <a href="4-prp.html#SP13">§13</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">linked_list</span><span class="plain-syntax"> *</span><span class="identifier-syntax">L</span><span class="plain-syntax">, </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">name</span><span class="plain-syntax">,</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">parameter_specification</span><span class="plain-syntax">,</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">void</span><span class="plain-syntax"> (*</span><span class="identifier-syntax">expander</span><span class="plain-syntax">)(</span><span class="reserved-syntax">preprocessor_macro</span><span class="plain-syntax"> *, </span><span class="reserved-syntax">preprocessor_state</span><span class="plain-syntax"> *, </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> **, </span><span class="reserved-syntax">preprocessor_loop</span><span class="plain-syntax"> *, </span><span class="reserved-syntax">text_file_position</span><span class="plain-syntax"> *),</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">text_file_position</span><span class="plain-syntax"> *</span><span class="identifier-syntax">tfp</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="4-prp.html#SP14" class="function-link"><span class="function-syntax">Preprocessor::find_macro</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">L</span><span class="plain-syntax">, </span><span class="identifier-syntax">name</span><span class="plain-syntax">))</span>
|
|
<span class="plain-syntax"> </span><a href="3-em.html#SP5" class="function-link"><span class="function-syntax">Errors::in_text_file</span></a><span class="plain-syntax">(</span><span class="string-syntax">"a macro with this name already exists"</span><span class="plain-syntax">, </span><span class="identifier-syntax">tfp</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">preprocessor_macro</span><span class="plain-syntax"> *</span><span class="identifier-syntax">new_macro</span><span class="plain-syntax"> = </span><span class="identifier-syntax">CREATE</span><span class="plain-syntax">(</span><span class="reserved-syntax">preprocessor_macro</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-prp.html#SP11_1" class="named-paragraph-link"><span class="named-paragraph">Initialise the macro</span><span class="named-paragraph-number">11.1</span></a></span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-prp.html#SP11_2" class="named-paragraph-link"><span class="named-paragraph">Parse the parameter list</span><span class="named-paragraph-number">11.2</span></a></span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">ADD_TO_LINKED_LIST</span><span class="plain-syntax">(</span><span class="identifier-syntax">new_macro</span><span class="plain-syntax">, </span><span class="reserved-syntax">preprocessor_macro</span><span class="plain-syntax">, </span><span class="identifier-syntax">L</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">new_macro</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax">}</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP11_1" class="paragraph-anchor"></a><b>§11.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Initialise the macro</span><span class="named-paragraph-number">11.1</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">new_macro</span><span class="plain-syntax">-></span><span class="element-syntax">identifier</span><span class="plain-syntax"> = </span><a href="4-sm.html#SP3" class="function-link"><span class="function-syntax">Str::duplicate</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">name</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">new_macro</span><span class="plain-syntax">-></span><span class="element-syntax">no_parameters</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">new_macro</span><span class="plain-syntax">-></span><span class="element-syntax">no_lines</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">new_macro</span><span class="plain-syntax">-></span><span class="element-syntax">expander</span><span class="plain-syntax"> = </span><span class="identifier-syntax">expander</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">new_macro</span><span class="plain-syntax">-></span><span class="element-syntax">begins_loop</span><span class="plain-syntax"> = </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">new_macro</span><span class="plain-syntax">-></span><span class="element-syntax">ends_loop</span><span class="plain-syntax"> = </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">new_macro</span><span class="plain-syntax">-></span><span class="element-syntax">loop_name</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">new_macro</span><span class="plain-syntax">-></span><span class="element-syntax">span</span><span class="plain-syntax"> = </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">;</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">new_macro</span><span class="plain-syntax">-></span><span class="element-syntax">suppress_newline_after_expanding</span><span class="plain-syntax"> = </span><span class="constant-syntax">TRUE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">new_macro</span><span class="plain-syntax">-></span><span class="element-syntax">suppress_whitespace_when_expanding</span><span class="plain-syntax"> = </span><span class="constant-syntax">TRUE</span><span class="plain-syntax">;</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="4-prp.html#SP11">§11</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP11_2" class="paragraph-anchor"></a><b>§11.2. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Parse the parameter list</span><span class="named-paragraph-number">11.2</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">spec</span><span class="plain-syntax"> = </span><a href="4-sm.html#SP3" class="function-link"><span class="function-syntax">Str::duplicate</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">parameter_specification</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">match_results</span><span class="plain-syntax"> </span><span class="identifier-syntax">mr</span><span class="plain-syntax"> = </span><a href="4-pm.html#SP9" class="function-link"><span class="function-syntax">Regexp::create_mr</span></a><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">while</span><span class="plain-syntax"> (</span><a href="4-pm.html#SP10" class="function-link"><span class="function-syntax">Regexp::match</span></a><span class="plain-syntax">(&</span><span class="identifier-syntax">mr</span><span class="plain-syntax">, </span><span class="identifier-syntax">spec</span><span class="plain-syntax">, </span><span class="identifier-syntax">L</span><span class="string-syntax">" *(%C+): *(%C+) *(%c*)"</span><span class="plain-syntax">)) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">par_name</span><span class="plain-syntax"> = </span><span class="identifier-syntax">mr</span><span class="plain-syntax">.</span><span class="element-syntax">exp</span><span class="plain-syntax">[0];</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">token_name</span><span class="plain-syntax"> = </span><span class="identifier-syntax">mr</span><span class="plain-syntax">.</span><span class="element-syntax">exp</span><span class="plain-syntax">[1];</span>
|
|
<span class="plain-syntax"> </span><a href="4-sm.html#SP15" class="function-link"><span class="function-syntax">Str::clear</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">spec</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><a href="4-sm.html#SP17" class="function-link"><span class="function-syntax">Str::copy</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">spec</span><span class="plain-syntax">, </span><span class="identifier-syntax">mr</span><span class="plain-syntax">.</span><span class="element-syntax">exp</span><span class="plain-syntax">[2]);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">new_macro</span><span class="plain-syntax">-></span><span class="element-syntax">no_parameters</span><span class="plain-syntax"> >= </span><span class="constant-syntax">MAX_PP_MACRO_PARAMETERS</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><a href="3-em.html#SP5" class="function-link"><span class="function-syntax">Errors::in_text_file</span></a><span class="plain-syntax">(</span><span class="string-syntax">"too many parameters in this definition"</span><span class="plain-syntax">, </span><span class="identifier-syntax">tfp</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-prp.html#SP11_2_1" class="named-paragraph-link"><span class="named-paragraph">Add parameter to macro</span><span class="named-paragraph-number">11.2.1</span></a></span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><a href="4-pm.html#SP9" class="function-link"><span class="function-syntax">Regexp::dispose_of</span></a><span class="plain-syntax">(&</span><span class="identifier-syntax">mr</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="4-sm.html#SP23" class="function-link"><span class="function-syntax">Str::is_whitespace</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">spec</span><span class="plain-syntax">) == </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> </span><a href="3-em.html#SP5" class="function-link"><span class="function-syntax">Errors::in_text_file</span></a><span class="plain-syntax">(</span><span class="string-syntax">"parameter list for this definition is malformed"</span><span class="plain-syntax">, </span><span class="identifier-syntax">tfp</span><span class="plain-syntax">);</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="4-prp.html#SP11">§11</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP11_2_1" class="paragraph-anchor"></a><b>§11.2.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Add parameter to macro</span><span class="named-paragraph-number">11.2.1</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">preprocessor_macro_parameter</span><span class="plain-syntax"> *</span><span class="identifier-syntax">new_parameter</span><span class="plain-syntax"> = </span><span class="identifier-syntax">CREATE</span><span class="plain-syntax">(</span><span class="reserved-syntax">preprocessor_macro_parameter</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">new_parameter</span><span class="plain-syntax">-></span><span class="element-syntax">name</span><span class="plain-syntax"> = </span><a href="4-sm.html#SP3" class="function-link"><span class="function-syntax">Str::duplicate</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">par_name</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">new_parameter</span><span class="plain-syntax">-></span><span class="element-syntax">definition_token</span><span class="plain-syntax"> = </span><a href="4-sm.html#SP3" class="function-link"><span class="function-syntax">Str::duplicate</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">token_name</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">new_parameter</span><span class="plain-syntax">-></span><span class="element-syntax">optional</span><span class="plain-syntax"> = </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="4-sm.html#SP13" class="function-link"><span class="function-syntax">Str::get_first_char</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">new_parameter</span><span class="plain-syntax">-></span><span class="element-syntax">name</span><span class="plain-syntax">) == </span><span class="character-syntax">'?'</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">new_parameter</span><span class="plain-syntax">-></span><span class="element-syntax">optional</span><span class="plain-syntax"> = </span><span class="constant-syntax">TRUE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><a href="4-sm.html#SP25" class="function-link"><span class="function-syntax">Str::delete_first_character</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">new_parameter</span><span class="plain-syntax">-></span><span class="element-syntax">name</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">new_macro</span><span class="plain-syntax">-></span><span class="element-syntax">parameters</span><span class="plain-syntax">[</span><span class="identifier-syntax">new_macro</span><span class="plain-syntax">-></span><span class="element-syntax">no_parameters</span><span class="plain-syntax">++] = </span><span class="identifier-syntax">new_parameter</span><span class="plain-syntax">;</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="4-prp.html#SP11_2">§11.2</a>.</li></ul>
|
|
<p class="commentary firstcommentary"><a id="SP12" class="paragraph-anchor"></a><b>§12. </b>We can then add lines to a macro (though this will only have an effect if its
|
|
expander function is <a href="4-prp.html#SP15" class="internal">Preprocessor::default_expander</a>).
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Preprocessor::add_line_to_macro</span><button class="popup" onclick="togglePopup('usagePopup13')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup13">Usage of <span class="code-font"><span class="function-syntax">Preprocessor::add_line_to_macro</span></span>:<br/><a href="4-prp.html#SP3_2_3">§3.2.3</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">preprocessor_macro</span><span class="plain-syntax"> *</span><span class="identifier-syntax">mm</span><span class="plain-syntax">, </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">line</span><span class="plain-syntax">,</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">text_file_position</span><span class="plain-syntax"> *</span><span class="identifier-syntax">tfp</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">mm</span><span class="plain-syntax">-></span><span class="element-syntax">no_lines</span><span class="plain-syntax"> >= </span><span class="constant-syntax">MAX_PP_MACRO_LINES</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><a href="3-em.html#SP5" class="function-link"><span class="function-syntax">Errors::in_text_file</span></a><span class="plain-syntax">(</span><span class="string-syntax">"too many lines in this definition"</span><span class="plain-syntax">, </span><span class="identifier-syntax">tfp</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">mm</span><span class="plain-syntax">-></span><span class="element-syntax">lines</span><span class="plain-syntax">[</span><span class="identifier-syntax">mm</span><span class="plain-syntax">-></span><span class="element-syntax">no_lines</span><span class="plain-syntax">++] = </span><a href="4-sm.html#SP3" class="function-link"><span class="function-syntax">Str::duplicate</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">line</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax">}</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP13" class="paragraph-anchor"></a><b>§13. Reserved macros. </b>A few macros are "reserved", that is, have built-in meanings, and use expander
|
|
functions other than <a href="4-prp.html#SP15" class="internal">Preprocessor::default_expander</a>.
|
|
</p>
|
|
|
|
<p class="commentary">Some of these, the <span class="extract"><span class="extract-syntax">special_macros</span></span>, are supplied by the code calling the
|
|
preprocessor. Those will provide domain-specific functionality. But a few are
|
|
built in here and therefore work in every domain:
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="reserved-syntax">linked_list</span><span class="plain-syntax"> *</span><span class="function-syntax">Preprocessor::list_of_reserved_macros</span><button class="popup" onclick="togglePopup('usagePopup14')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup14">Usage of <span class="code-font"><span class="function-syntax">Preprocessor::list_of_reserved_macros</span></span>:<br/><a href="4-prp.html#SP1_2">§1.2</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">linked_list</span><span class="plain-syntax"> *</span><span class="identifier-syntax">special_macros</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">linked_list</span><span class="plain-syntax"> *</span><span class="identifier-syntax">L</span><span class="plain-syntax"> = </span><span class="identifier-syntax">NEW_LINKED_LIST</span><span class="plain-syntax">(</span><span class="reserved-syntax">preprocessor_macro</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><a href="4-prp.html#SP13" class="function-link"><span class="function-syntax">Preprocessor::new_loop_macro</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">L</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"repeat"</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"with: WITH in: IN"</span><span class="plain-syntax">,</span>
|
|
<span class="plain-syntax"> </span><a href="4-prp.html#SP17" class="function-link"><span class="function-syntax">Preprocessor::repeat_expander</span></a><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><a href="4-prp.html#SP11" class="function-link"><span class="function-syntax">Preprocessor::new_macro</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">L</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"set"</span><span class="plain-syntax">, </span><span class="identifier-syntax">I</span><span class="string-syntax">"name: NAME value: VALUE"</span><span class="plain-syntax">,</span>
|
|
<span class="plain-syntax"> </span><a href="4-prp.html#SP16" class="function-link"><span class="function-syntax">Preprocessor::set_expander</span></a><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">);</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">preprocessor_macro</span><span class="plain-syntax"> *</span><span class="identifier-syntax">mm</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_LINKED_LIST</span><span class="plain-syntax">(</span><span class="identifier-syntax">mm</span><span class="plain-syntax">, </span><span class="reserved-syntax">preprocessor_macro</span><span class="plain-syntax">, </span><span class="identifier-syntax">special_macros</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">ADD_TO_LINKED_LIST</span><span class="plain-syntax">(</span><span class="identifier-syntax">mm</span><span class="plain-syntax">, </span><span class="reserved-syntax">preprocessor_macro</span><span class="plain-syntax">, </span><span class="identifier-syntax">L</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">L</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax">}</span>
|
|
|
|
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Preprocessor::do_not_suppress_whitespace</span><span class="plain-syntax">(</span><span class="reserved-syntax">preprocessor_macro</span><span class="plain-syntax"> *</span><span class="identifier-syntax">mm</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">mm</span><span class="plain-syntax">-></span><span class="element-syntax">suppress_newline_after_expanding</span><span class="plain-syntax"> = </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">mm</span><span class="plain-syntax">-></span><span class="element-syntax">suppress_whitespace_when_expanding</span><span class="plain-syntax"> = </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax">}</span>
|
|
|
|
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Preprocessor::new_loop_macro</span><span class="plain-syntax">(</span><span class="reserved-syntax">linked_list</span><span class="plain-syntax"> *</span><span class="identifier-syntax">L</span><span class="plain-syntax">, </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">name</span><span class="plain-syntax">,</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">parameter_specification</span><span class="plain-syntax">,</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">void</span><span class="plain-syntax"> (*</span><span class="identifier-syntax">expander</span><span class="plain-syntax">)(</span><span class="reserved-syntax">preprocessor_macro</span><span class="plain-syntax"> *, </span><span class="reserved-syntax">preprocessor_state</span><span class="plain-syntax"> *, </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> **, </span><span class="reserved-syntax">preprocessor_loop</span><span class="plain-syntax"> *, </span><span class="reserved-syntax">text_file_position</span><span class="plain-syntax"> *),</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">text_file_position</span><span class="plain-syntax"> *</span><span class="identifier-syntax">tfp</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">TEMPORARY_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">subname</span><span class="plain-syntax">)</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">subname</span><span class="plain-syntax">, </span><span class="string-syntax">"%S-block"</span><span class="plain-syntax">, </span><span class="identifier-syntax">name</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">preprocessor_macro</span><span class="plain-syntax"> *</span><span class="identifier-syntax">mm</span><span class="plain-syntax"> = </span><a href="4-prp.html#SP11" class="function-link"><span class="function-syntax">Preprocessor::new_macro</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">L</span><span class="plain-syntax">, </span><span class="identifier-syntax">subname</span><span class="plain-syntax">, </span><span class="identifier-syntax">parameter_specification</span><span class="plain-syntax">, </span><span class="identifier-syntax">expander</span><span class="plain-syntax">, </span><span class="identifier-syntax">tfp</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">mm</span><span class="plain-syntax">-></span><span class="element-syntax">begins_loop</span><span class="plain-syntax"> = </span><span class="constant-syntax">TRUE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">mm</span><span class="plain-syntax">-></span><span class="element-syntax">loop_name</span><span class="plain-syntax"> = </span><a href="4-sm.html#SP3" class="function-link"><span class="function-syntax">Str::duplicate</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">name</span><span class="plain-syntax">);</span>
|
|
|
|
<span class="plain-syntax"> </span><a href="4-sm.html#SP15" class="function-link"><span class="function-syntax">Str::clear</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">subname</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">subname</span><span class="plain-syntax">, </span><span class="string-syntax">"end-%S-block"</span><span class="plain-syntax">, </span><span class="identifier-syntax">name</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">mm</span><span class="plain-syntax"> = </span><a href="4-prp.html#SP11" class="function-link"><span class="function-syntax">Preprocessor::new_macro</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">L</span><span class="plain-syntax">, </span><span class="identifier-syntax">subname</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><a href="4-prp.html#SP18" class="function-link"><span class="function-syntax">Preprocessor::end_loop_expander</span></a><span class="plain-syntax">, </span><span class="identifier-syntax">tfp</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">mm</span><span class="plain-syntax">-></span><span class="element-syntax">ends_loop</span><span class="plain-syntax"> = </span><span class="constant-syntax">TRUE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">mm</span><span class="plain-syntax">-></span><span class="element-syntax">loop_name</span><span class="plain-syntax"> = </span><a href="4-sm.html#SP3" class="function-link"><span class="function-syntax">Str::duplicate</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">name</span><span class="plain-syntax">);</span>
|
|
|
|
<span class="plain-syntax"> </span><a href="4-sm.html#SP15" class="function-link"><span class="function-syntax">Str::clear</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">subname</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">subname</span><span class="plain-syntax">, </span><span class="string-syntax">"%S-span"</span><span class="plain-syntax">, </span><span class="identifier-syntax">name</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">mm</span><span class="plain-syntax"> = </span><a href="4-prp.html#SP11" class="function-link"><span class="function-syntax">Preprocessor::new_macro</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">L</span><span class="plain-syntax">, </span><span class="identifier-syntax">subname</span><span class="plain-syntax">, </span><span class="identifier-syntax">parameter_specification</span><span class="plain-syntax">, </span><span class="identifier-syntax">expander</span><span class="plain-syntax">, </span><span class="identifier-syntax">tfp</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">mm</span><span class="plain-syntax">-></span><span class="element-syntax">begins_loop</span><span class="plain-syntax"> = </span><span class="constant-syntax">TRUE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">mm</span><span class="plain-syntax">-></span><span class="element-syntax">loop_name</span><span class="plain-syntax"> = </span><a href="4-sm.html#SP3" class="function-link"><span class="function-syntax">Str::duplicate</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">name</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">mm</span><span class="plain-syntax">-></span><span class="element-syntax">span</span><span class="plain-syntax"> = </span><span class="constant-syntax">TRUE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><a href="4-prp.html#SP13" class="function-link"><span class="function-syntax">Preprocessor::do_not_suppress_whitespace</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">mm</span><span class="plain-syntax">);</span>
|
|
|
|
<span class="plain-syntax"> </span><a href="4-sm.html#SP15" class="function-link"><span class="function-syntax">Str::clear</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">subname</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">WRITE_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">subname</span><span class="plain-syntax">, </span><span class="string-syntax">"end-%S-span"</span><span class="plain-syntax">, </span><span class="identifier-syntax">name</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">mm</span><span class="plain-syntax"> = </span><a href="4-prp.html#SP11" class="function-link"><span class="function-syntax">Preprocessor::new_macro</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">L</span><span class="plain-syntax">, </span><span class="identifier-syntax">subname</span><span class="plain-syntax">, </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">, </span><a href="4-prp.html#SP18" class="function-link"><span class="function-syntax">Preprocessor::end_loop_expander</span></a><span class="plain-syntax">, </span><span class="identifier-syntax">tfp</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">mm</span><span class="plain-syntax">-></span><span class="element-syntax">ends_loop</span><span class="plain-syntax"> = </span><span class="constant-syntax">TRUE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">mm</span><span class="plain-syntax">-></span><span class="element-syntax">loop_name</span><span class="plain-syntax"> = </span><a href="4-sm.html#SP3" class="function-link"><span class="function-syntax">Str::duplicate</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">name</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">mm</span><span class="plain-syntax">-></span><span class="element-syntax">span</span><span class="plain-syntax"> = </span><span class="constant-syntax">TRUE</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><a href="4-prp.html#SP13" class="function-link"><span class="function-syntax">Preprocessor::do_not_suppress_whitespace</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">mm</span><span class="plain-syntax">);</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">subname</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax">}</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP14" class="paragraph-anchor"></a><b>§14. </b>Finding a macro in a list:
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="reserved-syntax">preprocessor_macro</span><span class="plain-syntax"> *</span><span class="function-syntax">Preprocessor::find_macro</span><button class="popup" onclick="togglePopup('usagePopup15')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup15">Usage of <span class="code-font"><span class="function-syntax">Preprocessor::find_macro</span></span>:<br/><a href="4-prp.html#SP4_1">§4.1</a>, <a href="4-prp.html#SP11">§11</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">linked_list</span><span class="plain-syntax"> *</span><span class="identifier-syntax">L</span><span class="plain-syntax">, </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">name</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">preprocessor_macro</span><span class="plain-syntax"> *</span><span class="identifier-syntax">mm</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_LINKED_LIST</span><span class="plain-syntax">(</span><span class="identifier-syntax">mm</span><span class="plain-syntax">, </span><span class="reserved-syntax">preprocessor_macro</span><span class="plain-syntax">, </span><span class="identifier-syntax">L</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="4-sm.html#SP19" class="function-link"><span class="function-syntax">Str::eq</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">mm</span><span class="plain-syntax">-></span><span class="element-syntax">identifier</span><span class="plain-syntax">, </span><span class="identifier-syntax">name</span><span class="plain-syntax">))</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">mm</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="identifier-syntax">NULL</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax">}</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP15" class="paragraph-anchor"></a><b>§15. The expander for user-defined macros. </b>All macros created by <span class="extract"><span class="extract-syntax">{define: ...}</span></span> are expanded by the following function.
|
|
It creates a local "stack frame" making the parameters available as variables,
|
|
then runs the definition lines through the scanner, then dismantles the stack
|
|
frame again.
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Preprocessor::default_expander</span><button class="popup" onclick="togglePopup('usagePopup16')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup16">Usage of <span class="code-font"><span class="function-syntax">Preprocessor::default_expander</span></span>:<br/><a href="4-prp.html#SP3_2_1">§3.2.1</a>, <a href="4-prp.html#SP3_2_2">§3.2.2</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">preprocessor_macro</span><span class="plain-syntax"> *</span><span class="identifier-syntax">mm</span><span class="plain-syntax">, </span><span class="reserved-syntax">preprocessor_state</span><span class="plain-syntax"> *</span><span class="identifier-syntax">PPS</span><span class="plain-syntax">,</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> **</span><span class="identifier-syntax">parameter_values</span><span class="plain-syntax">, </span><span class="reserved-syntax">preprocessor_loop</span><span class="plain-syntax"> *</span><span class="identifier-syntax">loop</span><span class="plain-syntax">, </span><span class="reserved-syntax">text_file_position</span><span class="plain-syntax"> *</span><span class="identifier-syntax">tfp</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-></span><span class="element-syntax">stack_frame</span><span class="plain-syntax"> = </span><a href="4-prp.html#SP7" class="function-link"><span class="function-syntax">Preprocessor::new_variable_set</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-></span><span class="element-syntax">stack_frame</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax">=0; </span><span class="identifier-syntax">i</span><span class="function-syntax"><mm-></span><span class="element-syntax">no_parameters</span><span class="plain-syntax">; </span><span class="identifier-syntax">i</span><span class="plain-syntax">++) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">preprocessor_variable</span><span class="plain-syntax"> *</span><span class="identifier-syntax">var</span><span class="plain-syntax"> =</span>
|
|
<span class="plain-syntax"> </span><a href="4-prp.html#SP8" class="function-link"><span class="function-syntax">Preprocessor::ensure_variable</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">mm</span><span class="plain-syntax">-></span><span class="element-syntax">parameters</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">]-></span><span class="element-syntax">definition_token</span><span class="plain-syntax">, </span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-></span><span class="element-syntax">stack_frame</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><a href="4-prp.html#SP6" class="function-link"><span class="function-syntax">Preprocessor::write_variable</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">var</span><span class="plain-syntax">, </span><span class="identifier-syntax">parameter_values</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">]);</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax"> (</span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">i</span><span class="plain-syntax">=0; </span><span class="identifier-syntax">i</span><span class="function-syntax"><mm-></span><span class="element-syntax">no_lines</span><span class="plain-syntax">; </span><span class="identifier-syntax">i</span><span class="plain-syntax">++)</span>
|
|
<span class="plain-syntax"> </span><a href="4-prp.html#SP3" class="function-link"><span class="function-syntax">Preprocessor::scan_line</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">mm</span><span class="plain-syntax">-></span><span class="element-syntax">lines</span><span class="plain-syntax">[</span><span class="identifier-syntax">i</span><span class="plain-syntax">], </span><span class="identifier-syntax">tfp</span><span class="plain-syntax">, (</span><span class="reserved-syntax">void</span><span class="plain-syntax"> *) </span><span class="identifier-syntax">PPS</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-></span><span class="element-syntax">stack_frame</span><span class="plain-syntax"> = </span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-></span><span class="element-syntax">stack_frame</span><span class="plain-syntax">-></span><span class="element-syntax">outer</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax">}</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP16" class="paragraph-anchor"></a><b>§16. The set expander. </b>An easy one.
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Preprocessor::set_expander</span><button class="popup" onclick="togglePopup('usagePopup17')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup17">Usage of <span class="code-font"><span class="function-syntax">Preprocessor::set_expander</span></span>:<br/><a href="4-prp.html#SP13">§13</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">preprocessor_macro</span><span class="plain-syntax"> *</span><span class="identifier-syntax">mm</span><span class="plain-syntax">, </span><span class="reserved-syntax">preprocessor_state</span><span class="plain-syntax"> *</span><span class="identifier-syntax">PPS</span><span class="plain-syntax">,</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> **</span><span class="identifier-syntax">parameter_values</span><span class="plain-syntax">, </span><span class="reserved-syntax">preprocessor_loop</span><span class="plain-syntax"> *</span><span class="identifier-syntax">loop</span><span class="plain-syntax">, </span><span class="reserved-syntax">text_file_position</span><span class="plain-syntax"> *</span><span class="identifier-syntax">tfp</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">name</span><span class="plain-syntax"> = </span><span class="identifier-syntax">parameter_values</span><span class="plain-syntax">[0];</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">value</span><span class="plain-syntax"> = </span><span class="identifier-syntax">parameter_values</span><span class="plain-syntax">[1];</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="4-prp.html#SP5" class="function-link"><span class="function-syntax">Preprocessor::acceptable_variable_name</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">name</span><span class="plain-syntax">) == </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> </span><a href="3-em.html#SP5" class="function-link"><span class="function-syntax">Errors::in_text_file</span></a><span class="plain-syntax">(</span><span class="string-syntax">"improper variable name"</span><span class="plain-syntax">, </span><span class="identifier-syntax">tfp</span><span class="plain-syntax">);</span>
|
|
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">preprocessor_variable</span><span class="plain-syntax"> *</span><span class="identifier-syntax">var</span><span class="plain-syntax"> = </span><a href="4-prp.html#SP8" class="function-link"><span class="function-syntax">Preprocessor::ensure_variable</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">name</span><span class="plain-syntax">, </span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-></span><span class="element-syntax">stack_frame</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><a href="4-prp.html#SP6" class="function-link"><span class="function-syntax">Preprocessor::write_variable</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">var</span><span class="plain-syntax">, </span><span class="identifier-syntax">value</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax">}</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP17" class="paragraph-anchor"></a><b>§17. The repeat expander. </b></p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Preprocessor::repeat_expander</span><button class="popup" onclick="togglePopup('usagePopup18')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup18">Usage of <span class="code-font"><span class="function-syntax">Preprocessor::repeat_expander</span></span>:<br/><a href="4-prp.html#SP13">§13</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">preprocessor_macro</span><span class="plain-syntax"> *</span><span class="identifier-syntax">mm</span><span class="plain-syntax">, </span><span class="reserved-syntax">preprocessor_state</span><span class="plain-syntax"> *</span><span class="identifier-syntax">PPS</span><span class="plain-syntax">,</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> **</span><span class="identifier-syntax">parameter_values</span><span class="plain-syntax">, </span><span class="reserved-syntax">preprocessor_loop</span><span class="plain-syntax"> *</span><span class="identifier-syntax">loop</span><span class="plain-syntax">, </span><span class="reserved-syntax">text_file_position</span><span class="plain-syntax"> *</span><span class="identifier-syntax">tfp</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">with</span><span class="plain-syntax"> = </span><span class="identifier-syntax">parameter_values</span><span class="plain-syntax">[0];</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">in</span><span class="plain-syntax"> = </span><span class="identifier-syntax">parameter_values</span><span class="plain-syntax">[1];</span>
|
|
<span class="plain-syntax"> </span><a href="4-prp.html#SP2" class="function-link"><span class="function-syntax">Preprocessor::set_loop_var_name</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">loop</span><span class="plain-syntax">, </span><span class="identifier-syntax">with</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">match_results</span><span class="plain-syntax"> </span><span class="identifier-syntax">mr</span><span class="plain-syntax"> = </span><a href="4-pm.html#SP9" class="function-link"><span class="function-syntax">Regexp::create_mr</span></a><span class="plain-syntax">();</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">while</span><span class="plain-syntax"> (</span><a href="4-pm.html#SP10" class="function-link"><span class="function-syntax">Regexp::match</span></a><span class="plain-syntax">(&</span><span class="identifier-syntax">mr</span><span class="plain-syntax">, </span><span class="identifier-syntax">in</span><span class="plain-syntax">, </span><span class="identifier-syntax">L</span><span class="string-syntax">"(%c*?),(%c*)"</span><span class="plain-syntax">)) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">value</span><span class="plain-syntax"> = </span><span class="identifier-syntax">mr</span><span class="plain-syntax">.</span><span class="element-syntax">exp</span><span class="plain-syntax">[0];</span>
|
|
<span class="plain-syntax"> </span><a href="4-sm.html#SP24" class="function-link"><span class="function-syntax">Str::trim_white_space</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">value</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><a href="4-prp.html#SP2" class="function-link"><span class="function-syntax">Preprocessor::add_loop_iteration</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">loop</span><span class="plain-syntax">, </span><span class="identifier-syntax">value</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><a href="4-sm.html#SP15" class="function-link"><span class="function-syntax">Str::clear</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">in</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><a href="4-sm.html#SP17" class="function-link"><span class="function-syntax">Str::copy</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">in</span><span class="plain-syntax">, </span><span class="identifier-syntax">mr</span><span class="plain-syntax">.</span><span class="element-syntax">exp</span><span class="plain-syntax">[1]);</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><a href="4-pm.html#SP9" class="function-link"><span class="function-syntax">Regexp::dispose_of</span></a><span class="plain-syntax">(&</span><span class="identifier-syntax">mr</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">value</span><span class="plain-syntax"> = </span><span class="identifier-syntax">in</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><a href="4-sm.html#SP24" class="function-link"><span class="function-syntax">Str::trim_white_space</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">value</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><a href="4-prp.html#SP2" class="function-link"><span class="function-syntax">Preprocessor::add_loop_iteration</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">loop</span><span class="plain-syntax">, </span><span class="identifier-syntax">value</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax">}</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP18" class="paragraph-anchor"></a><b>§18. The expander used for all loop ends. </b>The macros which open a loop just store up the name of the variable and the
|
|
range of its values: otherwise, they do nothing. It's only when the end of a
|
|
loop is reached that any expansion happens, and this is where.
|
|
</p>
|
|
|
|
<p class="commentary">We create a new stack frame inside the current one, and put the loop variable
|
|
into it. Then we run through the iteration values, setting the variable to
|
|
each in turn, and expand the material.
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="reserved-syntax">void</span><span class="plain-syntax"> </span><span class="function-syntax">Preprocessor::end_loop_expander</span><button class="popup" onclick="togglePopup('usagePopup19')"><span class="comment-syntax">?</span><span class="popuptext" id="usagePopup19">Usage of <span class="code-font"><span class="function-syntax">Preprocessor::end_loop_expander</span></span>:<br/><a href="4-prp.html#SP13">§13</a></span></button><span class="plain-syntax">(</span><span class="reserved-syntax">preprocessor_macro</span><span class="plain-syntax"> *</span><span class="identifier-syntax">mm</span><span class="plain-syntax">, </span><span class="reserved-syntax">preprocessor_state</span><span class="plain-syntax"> *</span><span class="identifier-syntax">PPS</span><span class="plain-syntax">,</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> **</span><span class="identifier-syntax">parameter_values</span><span class="plain-syntax">, </span><span class="reserved-syntax">preprocessor_loop</span><span class="plain-syntax"> *</span><span class="identifier-syntax">loop</span><span class="plain-syntax">, </span><span class="reserved-syntax">text_file_position</span><span class="plain-syntax"> *</span><span class="identifier-syntax">tfp</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-></span><span class="element-syntax">shadow_sp</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-></span><span class="element-syntax">repeat_sp</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><a href="3-em.html#SP5" class="function-link"><span class="function-syntax">Errors::in_text_file</span></a><span class="plain-syntax">(</span><span class="string-syntax">"end without repeat"</span><span class="plain-syntax">, </span><span class="identifier-syntax">tfp</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">preprocessor_loop</span><span class="plain-syntax"> *</span><span class="identifier-syntax">loop</span><span class="plain-syntax"> = &(</span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-></span><span class="element-syntax">repeat_data</span><span class="plain-syntax">[--(</span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-></span><span class="element-syntax">repeat_sp</span><span class="plain-syntax">)]);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">matter</span><span class="plain-syntax"> = </span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-></span><span class="element-syntax">dest</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-></span><span class="element-syntax">dest</span><span class="plain-syntax"> = </span><span class="identifier-syntax">loop</span><span class="plain-syntax">-></span><span class="element-syntax">repeat_saved_dest</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-></span><span class="element-syntax">stack_frame</span><span class="plain-syntax"> = </span><a href="4-prp.html#SP7" class="function-link"><span class="function-syntax">Preprocessor::new_variable_set</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-></span><span class="element-syntax">stack_frame</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">preprocessor_variable</span><span class="plain-syntax"> *</span><span class="identifier-syntax">loop_var</span><span class="plain-syntax"> =</span>
|
|
<span class="plain-syntax"> </span><a href="4-prp.html#SP8" class="function-link"><span class="function-syntax">Preprocessor::ensure_variable</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">loop</span><span class="plain-syntax">-></span><span class="element-syntax">loop_var_name</span><span class="plain-syntax">, </span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-></span><span class="element-syntax">stack_frame</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax"> *</span><span class="identifier-syntax">value</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_OVER_LINKED_LIST</span><span class="plain-syntax">(</span><span class="identifier-syntax">value</span><span class="plain-syntax">, </span><span class="reserved-syntax">text_stream</span><span class="plain-syntax">, </span><span class="identifier-syntax">loop</span><span class="plain-syntax">-></span><span class="element-syntax">iterations</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> </span><span class="named-paragraph-container code-font"><a href="4-prp.html#SP18_1" class="named-paragraph-link"><span class="named-paragraph">Iterate with this value</span><span class="named-paragraph-number">18.1</span></a></span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-></span><span class="element-syntax">stack_frame</span><span class="plain-syntax"> = </span><span class="identifier-syntax">PPS</span><span class="plain-syntax">-></span><span class="element-syntax">stack_frame</span><span class="plain-syntax">-></span><span class="element-syntax">outer</span><span class="plain-syntax">;</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax">}</span>
|
|
</pre>
|
|
<p class="commentary firstcommentary"><a id="SP18_1" class="paragraph-anchor"></a><b>§18.1. </b><span class="named-paragraph-container code-font"><span class="named-paragraph-defn">Iterate with this value</span><span class="named-paragraph-number">18.1</span></span><span class="comment-syntax"> =</span>
|
|
</p>
|
|
|
|
<pre class="displayed-code all-displayed-code code-font">
|
|
<span class="plain-syntax"> </span><a href="4-prp.html#SP6" class="function-link"><span class="function-syntax">Preprocessor::write_variable</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">loop_var</span><span class="plain-syntax">, </span><span class="identifier-syntax">value</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">mm</span><span class="plain-syntax">-></span><span class="element-syntax">span</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><a href="4-prp.html#SP4" class="function-link"><span class="function-syntax">Preprocessor::expand</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">matter</span><span class="plain-syntax">, </span><span class="identifier-syntax">tfp</span><span class="plain-syntax">, </span><span class="identifier-syntax">PPS</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">TEMPORARY_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">line</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">LOOP_THROUGH_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">pos</span><span class="plain-syntax">, </span><span class="identifier-syntax">matter</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><a href="4-sm.html#SP13" class="function-link"><span class="function-syntax">Str::get</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pos</span><span class="plain-syntax">) == </span><span class="character-syntax">'\n'</span><span class="plain-syntax">) {</span>
|
|
<span class="plain-syntax"> </span><a href="4-prp.html#SP3" class="function-link"><span class="function-syntax">Preprocessor::scan_line</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">line</span><span class="plain-syntax">, </span><span class="identifier-syntax">tfp</span><span class="plain-syntax">, (</span><span class="reserved-syntax">void</span><span class="plain-syntax"> *) </span><span class="identifier-syntax">PPS</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> </span><a href="4-sm.html#SP15" class="function-link"><span class="function-syntax">Str::clear</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">line</span><span class="plain-syntax">);</span>
|
|
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">PUT_TO</span><span class="plain-syntax">(</span><span class="identifier-syntax">line</span><span class="plain-syntax">, </span><a href="4-sm.html#SP13" class="function-link"><span class="function-syntax">Str::get</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pos</span><span class="plain-syntax">));</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> }</span>
|
|
<span class="plain-syntax"> </span><span class="identifier-syntax">DISCARD_TEXT</span><span class="plain-syntax">(</span><span class="identifier-syntax">line</span><span class="plain-syntax">)</span>
|
|
<span class="plain-syntax"> }</span>
|
|
</pre>
|
|
<ul class="endnotetexts"><li>This code is used in <a href="4-prp.html#SP18">§18</a>.</li></ul>
|
|
<nav role="progress"><div class="progresscontainer">
|
|
<ul class="progressbar"><li class="progressprev"><a href="4-tf.html">❮</a></li><li class="progresschapter"><a href="P-abgtf.html">P</a></li><li class="progresschapter"><a href="1-fm.html">1</a></li><li class="progresschapter"><a href="2-dl.html">2</a></li><li class="progresschapter"><a href="3-em.html">3</a></li><li class="progresscurrentchapter">4</li><li class="progresssection"><a href="4-chr.html">chr</a></li><li class="progresssection"><a href="4-cst.html">cst</a></li><li class="progresssection"><a href="4-ws.html">ws</a></li><li class="progresssection"><a href="4-sm.html">sm</a></li><li class="progresssection"><a href="4-tf.html">tf</a></li><li class="progresscurrent">prp</li><li class="progresssection"><a href="4-taa.html">taa</a></li><li class="progresssection"><a href="4-pm.html">pm</a></li><li class="progresschapter"><a href="5-htm.html">5</a></li><li class="progresschapter"><a href="6-bf.html">6</a></li><li class="progresschapter"><a href="7-vn.html">7</a></li><li class="progresschapter"><a href="8-ws.html">8</a></li><li class="progressnext"><a href="4-taa.html">❯</a></li></ul></div>
|
|
</nav><!--End of weave-->
|
|
|
|
</main>
|
|
</body>
|
|
</html>
|
|
|