1530 lines
196 KiB
HTML
1530 lines
196 KiB
HTML
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
|
<html>
|
|
<head>
|
|
<title>4/pl</title>
|
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
|
<meta http-equiv="Content-Language" content="en-gb">
|
|
<link href="inweb.css" rel="stylesheet" rev="stylesheet" type="text/css">
|
|
</head>
|
|
<body>
|
|
|
|
<!--Weave of '4/cl' generated by 7-->
|
|
<ul class="crumbs"><li><a href="../webs.html">★</a></li><li><a href="index.html">inweb 7</a></li><li><a href="index.html#4">Chapter 4: Languages</a></li><li><b>C-Like Languages</b></li></ul><p class="purpose">To provide special features for the whole C family of languages.</p>
|
|
|
|
<ul class="toc"><li><a href="#SP1">§1. Creation</a></li><li><a href="#SP2">§2. </a></li><li><a href="#SP3">§3. Parsing</a></li><li><a href="#SP3_2">§3.2. Structures</a></li><li><a href="#SP3_3">§3.3. Structure dependency</a></li><li><a href="#SP3_4">§3.4. Functions</a></li><li><a href="#SP5">§5. Subcategorisation</a></li><li><a href="#SP6">§6. Tangling extras</a></li><li><a href="#SP9">§9. Tangling predeclarations</a></li><li><a href="#SP10">§10. Line markers</a></li><li><a href="#SP11">§11. Comments</a></li><li><a href="#SP13">§13. Ifdefs</a></li><li><a href="#SP14">§14. Before and after expansion</a></li><li><a href="#SP15">§15. Begin weave</a></li><li><a href="#SP16">§16. Syntax colouring</a></li><li><a href="#SP19">§19. Overriding regular code weaving</a></li><li><a href="#SP20">§20. Analysis</a></li></ul><hr class="tocbar">
|
|
|
|
<p class="inwebparagraph"><a id="SP1"></a><b>§1. Creation. </b></p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">programming_language</span><span class="plain"> *</span><span class="functiontext">CLike::create_C</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
|
|
<span class="reserved">programming_language</span><span class="plain"> *</span><span class="identifier">pl</span><span class="plain"> = </span><span class="functiontext">Languages::new_language</span><span class="plain">(</span><span class="identifier">I</span><span class="string">"C"</span><span class="plain">, </span><span class="identifier">I</span><span class="string">".c"</span><span class="plain">);</span>
|
|
<span class="functiontext">CLike::make_c_like</span><span class="plain">(</span><span class="identifier">pl</span><span class="plain">);</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">pl</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
|
|
<span class="reserved">programming_language</span><span class="plain"> *</span><span class="functiontext">CLike::create_CPP</span><span class="plain">(</span><span class="reserved">void</span><span class="plain">) {</span>
|
|
<span class="reserved">programming_language</span><span class="plain"> *</span><span class="identifier">pl</span><span class="plain"> = </span><span class="functiontext">Languages::new_language</span><span class="plain">(</span><span class="identifier">I</span><span class="string">"C++"</span><span class="plain">, </span><span class="identifier">I</span><span class="string">".cpp"</span><span class="plain">);</span>
|
|
<span class="functiontext">CLike::make_c_like</span><span class="plain">(</span><span class="identifier">pl</span><span class="plain">);</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">pl</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function CLike::create_C is used in 4/pl (<a href="4-pl.html#SP3">§3</a>).</p>
|
|
|
|
<p class="endnote">The function CLike::create_CPP is used in 4/pl (<a href="4-pl.html#SP3">§3</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP2"></a><b>§2. </b>What makes a language C-like?
|
|
This does:
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">CLike::make_c_like</span><span class="plain">(</span><span class="reserved">programming_language</span><span class="plain"> *</span><span class="identifier">pl</span><span class="plain">) {</span>
|
|
<span class="identifier">pl</span><span class="plain">-</span><span class="element">>supports_enumerations</span><span class="plain"> = </span><span class="constant">TRUE</span><span class="plain">;</span>
|
|
|
|
<span class="identifier">METHOD_ADD</span><span class="plain">(</span><span class="identifier">pl</span><span class="plain">, </span><span class="constant">FURTHER_PARSING_PAR_MTID</span><span class="plain">, </span><span class="functiontext">CLike::further_parsing</span><span class="plain">);</span>
|
|
<span class="identifier">METHOD_ADD</span><span class="plain">(</span><span class="identifier">pl</span><span class="plain">, </span><span class="constant">SUBCATEGORISE_LINE_PAR_MTID</span><span class="plain">, </span><span class="functiontext">CLike::subcategorise_code</span><span class="plain">);</span>
|
|
|
|
<span class="identifier">METHOD_ADD</span><span class="plain">(</span><span class="identifier">pl</span><span class="plain">, </span><span class="constant">SHEBANG_TAN_MTID</span><span class="plain">, </span><span class="functiontext">CLike::shebang</span><span class="plain">);</span>
|
|
<span class="identifier">METHOD_ADD</span><span class="plain">(</span><span class="identifier">pl</span><span class="plain">, </span><span class="constant">ADDITIONAL_EARLY_MATTER_TAN_MTID</span><span class="plain">, </span><span class="functiontext">CLike::additional_early_matter</span><span class="plain">);</span>
|
|
<span class="identifier">METHOD_ADD</span><span class="plain">(</span><span class="identifier">pl</span><span class="plain">, </span><span class="constant">START_DEFN_TAN_MTID</span><span class="plain">, </span><span class="functiontext">CLike::start_definition</span><span class="plain">);</span>
|
|
<span class="identifier">METHOD_ADD</span><span class="plain">(</span><span class="identifier">pl</span><span class="plain">, </span><span class="constant">PROLONG_DEFN_TAN_MTID</span><span class="plain">, </span><span class="functiontext">CLike::prolong_definition</span><span class="plain">);</span>
|
|
<span class="identifier">METHOD_ADD</span><span class="plain">(</span><span class="identifier">pl</span><span class="plain">, </span><span class="constant">END_DEFN_TAN_MTID</span><span class="plain">, </span><span class="functiontext">CLike::end_definition</span><span class="plain">);</span>
|
|
<span class="identifier">METHOD_ADD</span><span class="plain">(</span><span class="identifier">pl</span><span class="plain">, </span><span class="constant">ADDITIONAL_PREDECLARATIONS_TAN_MTID</span><span class="plain">, </span><span class="functiontext">CLike::additional_predeclarations</span><span class="plain">);</span>
|
|
<span class="identifier">METHOD_ADD</span><span class="plain">(</span><span class="identifier">pl</span><span class="plain">, </span><span class="constant">INSERT_LINE_MARKER_TAN_MTID</span><span class="plain">, </span><span class="functiontext">CLike::insert_line_marker</span><span class="plain">);</span>
|
|
<span class="identifier">METHOD_ADD</span><span class="plain">(</span><span class="identifier">pl</span><span class="plain">, </span><span class="constant">BEFORE_MACRO_EXPANSION_TAN_MTID</span><span class="plain">, </span><span class="functiontext">CLike::before_macro_expansion</span><span class="plain">);</span>
|
|
<span class="identifier">METHOD_ADD</span><span class="plain">(</span><span class="identifier">pl</span><span class="plain">, </span><span class="constant">AFTER_MACRO_EXPANSION_TAN_MTID</span><span class="plain">, </span><span class="functiontext">CLike::after_macro_expansion</span><span class="plain">);</span>
|
|
<span class="identifier">METHOD_ADD</span><span class="plain">(</span><span class="identifier">pl</span><span class="plain">, </span><span class="constant">COMMENT_TAN_MTID</span><span class="plain">, </span><span class="functiontext">CLike::comment</span><span class="plain">);</span>
|
|
<span class="identifier">METHOD_ADD</span><span class="plain">(</span><span class="identifier">pl</span><span class="plain">, </span><span class="constant">OPEN_IFDEF_TAN_MTID</span><span class="plain">, </span><span class="functiontext">CLike::open_ifdef</span><span class="plain">);</span>
|
|
<span class="identifier">METHOD_ADD</span><span class="plain">(</span><span class="identifier">pl</span><span class="plain">, </span><span class="constant">CLOSE_IFDEF_TAN_MTID</span><span class="plain">, </span><span class="functiontext">CLike::close_ifdef</span><span class="plain">);</span>
|
|
<span class="identifier">METHOD_ADD</span><span class="plain">(</span><span class="identifier">pl</span><span class="plain">, </span><span class="constant">PARSE_COMMENT_TAN_MTID</span><span class="plain">, </span><span class="functiontext">CLike::parse_comment</span><span class="plain">);</span>
|
|
|
|
<span class="identifier">METHOD_ADD</span><span class="plain">(</span><span class="identifier">pl</span><span class="plain">, </span><span class="constant">BEGIN_WEAVE_WEA_MTID</span><span class="plain">, </span><span class="functiontext">CLike::begin_weave</span><span class="plain">);</span>
|
|
<span class="identifier">METHOD_ADD</span><span class="plain">(</span><span class="identifier">pl</span><span class="plain">, </span><span class="constant">RESET_SYNTAX_COLOURING_WEA_MTID</span><span class="plain">, </span><span class="functiontext">CLike::reset_syntax_colouring</span><span class="plain">);</span>
|
|
<span class="identifier">METHOD_ADD</span><span class="plain">(</span><span class="identifier">pl</span><span class="plain">, </span><span class="constant">SYNTAX_COLOUR_WEA_MTID</span><span class="plain">, </span><span class="functiontext">CLike::syntax_colour</span><span class="plain">);</span>
|
|
|
|
<span class="identifier">METHOD_ADD</span><span class="plain">(</span><span class="identifier">pl</span><span class="plain">, </span><span class="constant">CATALOGUE_ANA_MTID</span><span class="plain">, </span><span class="functiontext">CLike::catalogue</span><span class="plain">);</span>
|
|
<span class="identifier">METHOD_ADD</span><span class="plain">(</span><span class="identifier">pl</span><span class="plain">, </span><span class="constant">EARLY_PREWEAVE_ANALYSIS_ANA_MTID</span><span class="plain">, </span><span class="functiontext">CLike::analyse_code</span><span class="plain">);</span>
|
|
<span class="identifier">METHOD_ADD</span><span class="plain">(</span><span class="identifier">pl</span><span class="plain">, </span><span class="constant">LATE_PREWEAVE_ANALYSIS_ANA_MTID</span><span class="plain">, </span><span class="functiontext">CLike::post_analysis</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function CLike::make_c_like is used in <a href="#SP1">§1</a>, 4/is (<a href="4-is.html#SP1">§1</a>).</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP3"></a><b>§3. Parsing. </b>After a web has been read in and then parsed, code supporting its language
|
|
is then called to do any further parsing it might want to. The code below
|
|
is run if the language is "C-like": regular C and InC both qualify.
|
|
</p>
|
|
|
|
<p class="inwebparagraph">In scanning the web, we need to keep track of <code class="display"><span class="extract">#ifdef</span></code> and <code class="display"><span class="extract">#endif</span></code> pairs
|
|
in the source. This matters because we will want to predeclare functions;
|
|
but if functions are declared in conditional compilation, then their
|
|
predeclarations have to be made under the same conditions.
|
|
</p>
|
|
|
|
<p class="inwebparagraph">The following stack holds the current set of conditional compilations which the
|
|
source line being scanned lies within.
|
|
</p>
|
|
|
|
|
|
<pre class="definitions">
|
|
<span class="definitionkeyword">define</span> <span class="constant">MAX_CONDITIONAL_COMPILATION_STACK</span><span class="plain"> 8</span>
|
|
</pre>
|
|
|
|
<pre class="display">
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">cc_sp</span><span class="plain"> = 0;</span>
|
|
<span class="reserved">source_line</span><span class="plain"> *</span><span class="identifier">cc_stack</span><span class="plain">[</span><span class="constant">MAX_CONDITIONAL_COMPILATION_STACK</span><span class="plain">];</span>
|
|
<span class="reserved">c_structure</span><span class="plain"> *</span><span class="identifier">first_cst_alphabetically</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">CLike::further_parsing</span><span class="plain">(</span><span class="reserved">programming_language</span><span class="plain"> *</span><span class="identifier">self</span><span class="plain">, </span><span class="reserved">web</span><span class="plain"> *</span><span class="identifier">W</span><span class="plain">) {</span>
|
|
<<span class="cwebmacro">Find every typedef struct in the tangle</span> <span class="cwebmacronumber">3.2</span>><span class="plain">;</span>
|
|
<<span class="cwebmacro">Work out which structs contain which others</span> <span class="cwebmacronumber">3.3</span>><span class="plain">;</span>
|
|
<span class="identifier">cc_sp</span><span class="plain"> = 0;</span>
|
|
<span class="reserved">chapter</span><span class="plain"> *</span><span class="identifier">C</span><span class="plain">;</span>
|
|
<span class="reserved">section</span><span class="plain"> *</span><span class="identifier">S</span><span class="plain">;</span>
|
|
<span class="identifier">LOOP_WITHIN_TANGLE</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">, </span><span class="identifier">S</span><span class="plain">, </span><span class="functiontext">Tangler::primary_target</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">))</span>
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">L</span><span class="plain">-</span><span class="element">>category</span><span class="plain"> == </span><span class="constant">CODE_BODY_LCAT</span><span class="plain">) ||</span>
|
|
<span class="plain">(</span><span class="identifier">L</span><span class="plain">-</span><span class="element">>category</span><span class="plain"> == </span><span class="constant">BEGIN_DEFINITION_LCAT</span><span class="plain">) ||</span>
|
|
<span class="plain">(</span><span class="identifier">L</span><span class="plain">-</span><span class="element">>category</span><span class="plain"> == </span><span class="constant">CONT_DEFINITION_LCAT</span><span class="plain">)) {</span>
|
|
<<span class="cwebmacro">Look for conditional compilation on this line</span> <span class="cwebmacronumber">3.1</span>><span class="plain">;</span>
|
|
<<span class="cwebmacro">Look for a function definition on this line</span> <span class="cwebmacronumber">3.4</span>><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">cc_sp</span><span class="plain"> > 0)</span>
|
|
<span class="functiontext">Main::error_in_web</span><span class="plain">(</span><span class="identifier">I</span><span class="string">"program ended with conditional compilation open"</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function CLike::further_parsing is used in <a href="#SP2">§2</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP3_1"></a><b>§3.1. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Look for conditional compilation on this line</span> <span class="cwebmacronumber">3.1</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="reserved">match_results</span><span class="plain"> </span><span class="identifier">mr</span><span class="plain"> = </span><span class="functiontext">Regexp::create_mr</span><span class="plain">();</span>
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="functiontext">Regexp::match</span><span class="plain">(&</span><span class="identifier">mr</span><span class="plain">, </span><span class="identifier">L</span><span class="plain">-</span><span class="element">>text</span><span class="plain">, </span><span class="identifier">L</span><span class="string">" *#ifn*def %c+"</span><span class="plain">)) ||</span>
|
|
<span class="plain">(</span><span class="functiontext">Regexp::match</span><span class="plain">(&</span><span class="identifier">mr</span><span class="plain">, </span><span class="identifier">L</span><span class="plain">-</span><span class="element">>text</span><span class="plain">, </span><span class="identifier">L</span><span class="string">" *#IFN*DEF %c+"</span><span class="plain">))) {</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">cc_sp</span><span class="plain"> >= </span><span class="constant">MAX_CONDITIONAL_COMPILATION_STACK</span><span class="plain">)</span>
|
|
<span class="functiontext">Main::error_in_web</span><span class="plain">(</span><span class="identifier">I</span><span class="string">"conditional compilation too deeply nested"</span><span class="plain">, </span><span class="identifier">L</span><span class="plain">);</span>
|
|
<span class="reserved">else</span>
|
|
<span class="identifier">cc_stack</span><span class="plain">[</span><span class="identifier">cc_sp</span><span class="plain">++] = </span><span class="identifier">L</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="functiontext">Regexp::match</span><span class="plain">(&</span><span class="identifier">mr</span><span class="plain">, </span><span class="identifier">L</span><span class="plain">-</span><span class="element">>text</span><span class="plain">, </span><span class="identifier">L</span><span class="string">" *#endif *"</span><span class="plain">)) ||</span>
|
|
<span class="plain">(</span><span class="functiontext">Regexp::match</span><span class="plain">(&</span><span class="identifier">mr</span><span class="plain">, </span><span class="identifier">L</span><span class="plain">-</span><span class="element">>text</span><span class="plain">, </span><span class="identifier">L</span><span class="string">" *#ENDIF *"</span><span class="plain">))) {</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">cc_sp</span><span class="plain"> <= 0)</span>
|
|
<span class="functiontext">Main::error_in_web</span><span class="plain">(</span><span class="identifier">I</span><span class="string">"found #endif without #ifdef or #ifndef"</span><span class="plain">, </span><span class="identifier">L</span><span class="plain">);</span>
|
|
<span class="reserved">else</span>
|
|
<span class="identifier">cc_sp</span><span class="plain">--;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP3">§3</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP3_2"></a><b>§3.2. Structures. </b>We're going to assume that the C source code uses structures looking
|
|
something like this:
|
|
</p>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="plain">typedef struct fruit {</span>
|
|
<span class="plain"> struct pip the_pips[5];</span>
|
|
<span class="plain"> struct fruit *often_confused_with;</span>
|
|
<span class="plain"> struct tree_species *grows_on;</span>
|
|
<span class="plain"> int typical_weight;</span>
|
|
<span class="plain">} fruit;</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph">which adopts the traditional layout conventions of Kernighan and Ritchie.
|
|
The structure definitions in this Inweb web all take the required form,
|
|
of course, and provide many more examples.
|
|
</p>
|
|
|
|
<p class="inwebparagraph">Note that a <code class="display"><span class="extract">fruit</span></code> structure contains a <code class="display"><span class="extract">pip</span></code> structure (in fact, five of
|
|
them), but only contains pointers to <code class="display"><span class="extract">tree_species</span></code> structures and itself.
|
|
C requires therefore that the structure definition for <code class="display"><span class="extract">pip</span></code> must occur
|
|
earlier in the code than that for <code class="display"><span class="extract">fruit</span></code>. This is a nuisance, so Inweb
|
|
takes care of it automatically.
|
|
</p>
|
|
|
|
|
|
<p class="macrodefinition"><code class="display">
|
|
<<span class="cwebmacrodefn">Find every typedef struct in the tangle</span> <span class="cwebmacronumber">3.2</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="reserved">c_structure</span><span class="plain"> *</span><span class="identifier">current_str</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="reserved">chapter</span><span class="plain"> *</span><span class="identifier">C</span><span class="plain">;</span>
|
|
<span class="reserved">section</span><span class="plain"> *</span><span class="identifier">S</span><span class="plain">;</span>
|
|
<span class="identifier">LOOP_WITHIN_TANGLE</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">, </span><span class="identifier">S</span><span class="plain">, </span><span class="functiontext">Tangler::primary_target</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">)) {</span>
|
|
<span class="reserved">match_results</span><span class="plain"> </span><span class="identifier">mr</span><span class="plain"> = </span><span class="functiontext">Regexp::create_mr</span><span class="plain">();</span>
|
|
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Regexp::match</span><span class="plain">(&</span><span class="identifier">mr</span><span class="plain">, </span><span class="identifier">L</span><span class="plain">-</span><span class="element">>text</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"typedef struct (%i+) %c*{%c*"</span><span class="plain">)) {</span>
|
|
<<span class="cwebmacro">Attach a structure to this source line</span> <span class="cwebmacronumber">3.2.2</span>><span class="plain">;</span>
|
|
<span class="functiontext">Tags::add_by_name</span><span class="plain">(</span><span class="identifier">L</span><span class="plain">-</span><span class="element">>owning_paragraph</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Structures"</span><span class="plain">);</span>
|
|
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> </span><span class="reserved">if</span><span class="plain"> ((</span><span class="functiontext">Str::get_first_char</span><span class="plain">(</span><span class="identifier">L</span><span class="plain">-</span><span class="element">>text</span><span class="plain">) == </span><span class="character">'}'</span><span class="plain">) && (</span><span class="identifier">current_str</span><span class="plain">)) {</span>
|
|
<span class="identifier">current_str</span><span class="plain">-</span><span class="element">>typedef_ends</span><span class="plain"> = </span><span class="identifier">L</span><span class="plain">;</span>
|
|
<span class="identifier">current_str</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> </span><span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">current_str</span><span class="plain">) && (</span><span class="identifier">current_str</span><span class="plain">-</span><span class="element">>typedef_ends</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">)) {</span>
|
|
<<span class="cwebmacro">Work through the a line in the structure definition</span> <span class="cwebmacronumber">3.2.3</span>><span class="plain">;</span>
|
|
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> </span><span class="reserved">if</span><span class="plain"> ((</span><span class="functiontext">Regexp::match</span><span class="plain">(&</span><span class="identifier">mr</span><span class="plain">, </span><span class="identifier">L</span><span class="plain">-</span><span class="element">>text</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"typedef %c+"</span><span class="plain">)) &&</span>
|
|
<span class="plain">(</span><span class="functiontext">Regexp::match</span><span class="plain">(&</span><span class="identifier">mr</span><span class="plain">, </span><span class="identifier">L</span><span class="plain">-</span><span class="element">>text</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"%c+##%c+"</span><span class="plain">) == </span><span class="constant">FALSE</span><span class="plain">)) {</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">L</span><span class="plain">-</span><span class="element">>owning_paragraph</span><span class="plain">-</span><span class="element">>placed_very_early</span><span class="plain"> == </span><span class="constant">FALSE</span><span class="plain">)</span>
|
|
<span class="identifier">L</span><span class="plain">-</span><span class="element">>category</span><span class="plain"> = </span><span class="constant">TYPEDEF_LCAT</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
<span class="functiontext">Regexp::dispose_of</span><span class="plain">(&</span><span class="identifier">mr</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP3">§3</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP3_2_1"></a><b>§3.2.1. </b>For each <code class="display"><span class="extract">typedef struct</span></code> we find, we will make one of these:
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">typedef</span><span class="plain"> </span><span class="reserved">struct</span><span class="plain"> </span><span class="reserved">c_structure</span><span class="plain"> {</span>
|
|
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">structure_name</span><span class="plain">;</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">tangled</span><span class="plain">; </span> <span class="comment">whether the structure definition has been tangled out</span>
|
|
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">source_line</span><span class="plain"> *</span><span class="identifier">typedef_begins</span><span class="plain">; </span> <span class="comment">opening line of <code class="display"><span class="extract">typedef</span></code></span>
|
|
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">source_line</span><span class="plain"> *</span><span class="identifier">typedef_ends</span><span class="plain">; </span> <span class="comment">closing line, where <code class="display"><span class="extract">}</span></code> appears</span>
|
|
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">linked_list</span><span class="plain"> *</span><span class="identifier">incorporates</span><span class="plain">; </span> <span class="comment">of <code class="display"><span class="extract">c_structure</span></code></span>
|
|
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">linked_list</span><span class="plain"> *</span><span class="identifier">elements</span><span class="plain">; </span> <span class="comment">of <code class="display"><span class="extract">structure_element</span></code></span>
|
|
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">c_structure</span><span class="plain"> *</span><span class="identifier">next_cst_alphabetically</span><span class="plain">;</span>
|
|
<span class="constant">MEMORY_MANAGEMENT</span>
|
|
<span class="plain">} </span><span class="reserved">c_structure</span><span class="plain">;</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The structure c_structure is accessed in 3/tw and here.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP3_2_2"></a><b>§3.2.2. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Attach a structure to this source line</span> <span class="cwebmacronumber">3.2.2</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="reserved">c_structure</span><span class="plain"> *</span><span class="identifier">str</span><span class="plain"> = </span><span class="identifier">CREATE</span><span class="plain">(</span><span class="reserved">c_structure</span><span class="plain">);</span>
|
|
<<span class="cwebmacro">Initialise the C structure structure</span> <span class="cwebmacronumber">3.2.2.1</span>><span class="plain">;</span>
|
|
<span class="functiontext">Analyser::mark_reserved_word</span><span class="plain">(</span><span class="identifier">L</span><span class="plain">-</span><span class="element">>owning_section</span><span class="plain">, </span><span class="identifier">str</span><span class="plain">-</span><span class="element">>structure_name</span><span class="plain">, </span><span class="constant">RESERVED_COLOUR</span><span class="plain">);</span>
|
|
<<span class="cwebmacro">Add this to the lists for its web and its paragraph</span> <span class="cwebmacronumber">3.2.2.2</span>><span class="plain">;</span>
|
|
<<span class="cwebmacro">Insertion-sort this into the alphabetical list of all structures found</span> <span class="cwebmacronumber">3.2.2.3</span>><span class="plain">;</span>
|
|
<span class="identifier">current_str</span><span class="plain"> = </span><span class="identifier">str</span><span class="plain">;</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP3_2">§3.2</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP3_2_2_1"></a><b>§3.2.2.1. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Initialise the C structure structure</span> <span class="cwebmacronumber">3.2.2.1</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="identifier">str</span><span class="plain">-</span><span class="element">>structure_name</span><span class="plain"> = </span><span class="functiontext">Str::duplicate</span><span class="plain">(</span><span class="identifier">mr</span><span class="element">.exp</span><span class="plain">[0]);</span>
|
|
<span class="identifier">str</span><span class="plain">-</span><span class="element">>typedef_begins</span><span class="plain"> = </span><span class="identifier">L</span><span class="plain">;</span>
|
|
<span class="identifier">str</span><span class="plain">-</span><span class="element">>tangled</span><span class="plain"> = </span><span class="constant">FALSE</span><span class="plain">;</span>
|
|
<span class="identifier">str</span><span class="plain">-</span><span class="element">>typedef_ends</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="identifier">str</span><span class="plain">-</span><span class="element">>incorporates</span><span class="plain"> = </span><span class="identifier">NEW_LINKED_LIST</span><span class="plain">(</span><span class="reserved">c_structure</span><span class="plain">);</span>
|
|
<span class="identifier">str</span><span class="plain">-</span><span class="element">>elements</span><span class="plain"> = </span><span class="identifier">NEW_LINKED_LIST</span><span class="plain">(</span><span class="reserved">structure_element</span><span class="plain">);</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP3_2_2">§3.2.2</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP3_2_2_2"></a><b>§3.2.2.2. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Add this to the lists for its web and its paragraph</span> <span class="cwebmacronumber">3.2.2.2</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="identifier">ADD_TO_LINKED_LIST</span><span class="plain">(</span><span class="identifier">str</span><span class="plain">, </span><span class="reserved">c_structure</span><span class="plain">, </span><span class="identifier">W</span><span class="plain">-</span><span class="element">>c_structures</span><span class="plain">);</span>
|
|
<span class="identifier">ADD_TO_LINKED_LIST</span><span class="plain">(</span><span class="identifier">str</span><span class="plain">, </span><span class="reserved">c_structure</span><span class="plain">, </span><span class="identifier">L</span><span class="plain">-</span><span class="element">>owning_paragraph</span><span class="plain">-</span><span class="element">>structures</span><span class="plain">);</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP3_2_2">§3.2.2</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP3_2_2_3"></a><b>§3.2.2.3. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Insertion-sort this into the alphabetical list of all structures found</span> <span class="cwebmacronumber">3.2.2.3</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="identifier">str</span><span class="plain">-</span><span class="element">>next_cst_alphabetically</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">first_cst_alphabetically</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) </span><span class="identifier">first_cst_alphabetically</span><span class="plain"> = </span><span class="identifier">str</span><span class="plain">;</span>
|
|
<span class="reserved">else</span><span class="plain"> {</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">placed</span><span class="plain"> = </span><span class="constant">FALSE</span><span class="plain">;</span>
|
|
<span class="reserved">c_structure</span><span class="plain"> *</span><span class="identifier">last</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="reserved">for</span><span class="plain"> (</span><span class="reserved">c_structure</span><span class="plain"> *</span><span class="identifier">seq</span><span class="plain"> = </span><span class="identifier">first_cst_alphabetically</span><span class="plain">; </span><span class="identifier">seq</span><span class="plain">;</span>
|
|
<span class="identifier">seq</span><span class="plain"> = </span><span class="identifier">seq</span><span class="plain">-</span><span class="element">>next_cst_alphabetically</span><span class="plain">) {</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Str::cmp</span><span class="plain">(</span><span class="identifier">str</span><span class="plain">-</span><span class="element">>structure_name</span><span class="plain">, </span><span class="identifier">seq</span><span class="plain">-</span><span class="element">>structure_name</span><span class="plain">) < 0) {</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">seq</span><span class="plain"> == </span><span class="identifier">first_cst_alphabetically</span><span class="plain">) {</span>
|
|
<span class="identifier">str</span><span class="plain">-</span><span class="element">>next_cst_alphabetically</span><span class="plain"> = </span><span class="identifier">first_cst_alphabetically</span><span class="plain">;</span>
|
|
<span class="identifier">first_cst_alphabetically</span><span class="plain"> = </span><span class="identifier">str</span><span class="plain">;</span>
|
|
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
|
|
<span class="identifier">last</span><span class="plain">-</span><span class="element">>next_cst_alphabetically</span><span class="plain"> = </span><span class="identifier">str</span><span class="plain">;</span>
|
|
<span class="identifier">str</span><span class="plain">-</span><span class="element">>next_cst_alphabetically</span><span class="plain"> = </span><span class="identifier">seq</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
<span class="identifier">placed</span><span class="plain"> = </span><span class="constant">TRUE</span><span class="plain">;</span>
|
|
<span class="reserved">break</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
<span class="identifier">last</span><span class="plain"> = </span><span class="identifier">seq</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">placed</span><span class="plain"> == </span><span class="constant">FALSE</span><span class="plain">) </span><span class="identifier">last</span><span class="plain">-</span><span class="element">>next_cst_alphabetically</span><span class="plain"> = </span><span class="identifier">str</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP3_2_2">§3.2.2</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP3_2_3"></a><b>§3.2.3. </b>At this point we're reading a line within the structure's definition; for
|
|
the sake of an illustrative example, let's suppose that line is:
|
|
</p>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="plain"> unsigned long long int *val;</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph">We need to extract the element name, <code class="display"><span class="extract">val</span></code>, and make a note of it.
|
|
</p>
|
|
|
|
|
|
<p class="macrodefinition"><code class="display">
|
|
<<span class="cwebmacrodefn">Work through the a line in the structure definition</span> <span class="cwebmacronumber">3.2.3</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">);</span>
|
|
<span class="functiontext">Str::copy</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">, </span><span class="identifier">L</span><span class="plain">-</span><span class="element">>text</span><span class="plain">);</span>
|
|
<span class="functiontext">Str::trim_white_space</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">);</span>
|
|
<<span class="cwebmacro">Remove C type modifiers from the front of p</span> <span class="cwebmacronumber">3.2.3.1</span>><span class="plain">;</span>
|
|
<span class="reserved">string_position</span><span class="plain"> </span><span class="identifier">pos</span><span class="plain"> = </span><span class="functiontext">Str::start</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Str::get</span><span class="plain">(</span><span class="identifier">pos</span><span class="plain">) != </span><span class="character">'/'</span><span class="plain">) { </span> <span class="comment">a slash must introduce a comment here</span>
|
|
<<span class="cwebmacro">Move pos past the type name</span> <span class="cwebmacronumber">3.2.3.2</span>><span class="plain">;</span>
|
|
<<span class="cwebmacro">Move pos past any typographical type modifiers</span> <span class="cwebmacronumber">3.2.3.3</span>><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Str::in_range</span><span class="plain">(</span><span class="identifier">pos</span><span class="plain">)) {</span>
|
|
<span class="reserved">match_results</span><span class="plain"> </span><span class="identifier">mr</span><span class="plain"> = </span><span class="functiontext">Regexp::create_mr</span><span class="plain">();</span>
|
|
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">elname</span><span class="plain">);</span>
|
|
<<span class="cwebmacro">Copy the element name into elname</span> <span class="cwebmacronumber">3.2.3.4</span>><span class="plain">;</span>
|
|
<<span class="cwebmacro">Record the element</span> <span class="cwebmacronumber">3.2.3.6</span>><span class="plain">;</span>
|
|
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">elname</span><span class="plain">);</span>
|
|
<span class="functiontext">Regexp::dispose_of</span><span class="plain">(&</span><span class="identifier">mr</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">}</span>
|
|
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">);</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP3_2">§3.2</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP3_2_3_1"></a><b>§3.2.3.1. </b>The following reduces <code class="display"><span class="extract">unsigned long long int *val;</span></code> to just <code class="display"><span class="extract">int *val;</span></code>.
|
|
</p>
|
|
|
|
|
|
<p class="macrodefinition"><code class="display">
|
|
<<span class="cwebmacrodefn">Remove C type modifiers from the front of p</span> <span class="cwebmacronumber">3.2.3.1</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="identifier">wchar_t</span><span class="plain"> *</span><span class="identifier">modifier_patterns</span><span class="plain">[] = {</span>
|
|
<span class="identifier">L</span><span class="string">"(struct )(%C%c*)"</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"(signed )(%C%c*)"</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"(unsigned )(%C%c*)"</span><span class="plain">,</span>
|
|
<span class="identifier">L</span><span class="string">"(short )(%C%c*)"</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"(long )(%C%c*)"</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"(static )(%C%c*)"</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain"> };</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">seek_modifiers</span><span class="plain"> = </span><span class="constant">TRUE</span><span class="plain">;</span>
|
|
<span class="reserved">while</span><span class="plain"> (</span><span class="identifier">seek_modifiers</span><span class="plain">) {</span>
|
|
<span class="identifier">seek_modifiers</span><span class="plain"> = </span><span class="constant">FALSE</span><span class="plain">;</span>
|
|
<span class="reserved">for</span><span class="plain"> (</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">i</span><span class="plain"> = 0; </span><span class="identifier">modifier_patterns</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">]; </span><span class="identifier">i</span><span class="plain">++)</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Regexp::match</span><span class="plain">(&</span><span class="identifier">mr</span><span class="plain">, </span><span class="identifier">p</span><span class="plain">, </span><span class="identifier">modifier_patterns</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">])) {</span>
|
|
<span class="functiontext">Str::copy</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">, </span><span class="identifier">mr</span><span class="element">.exp</span><span class="plain">[1]);</span>
|
|
<span class="identifier">seek_modifiers</span><span class="plain"> = </span><span class="constant">TRUE</span><span class="plain">;</span>
|
|
<span class="reserved">break</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP3_2_3">§3.2.3</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP3_2_3_2"></a><b>§3.2.3.2. </b>At this point <code class="display"><span class="extract">p</span></code> has been reduced to <code class="display"><span class="extract">int *val;</span></code>, but the following moves
|
|
<code class="display"><span class="extract">pos</span></code> to point to the <code class="display"><span class="extract">*</span></code>:
|
|
</p>
|
|
|
|
|
|
<p class="macrodefinition"><code class="display">
|
|
<<span class="cwebmacrodefn">Move pos past the type name</span> <span class="cwebmacronumber">3.2.3.2</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="reserved">while</span><span class="plain"> ((</span><span class="functiontext">Str::get</span><span class="plain">(</span><span class="identifier">pos</span><span class="plain">)) && (</span><span class="functiontext">Characters::is_space_or_tab</span><span class="plain">(</span><span class="functiontext">Str::get</span><span class="plain">(</span><span class="identifier">pos</span><span class="plain">)) == </span><span class="constant">FALSE</span><span class="plain">))</span>
|
|
<span class="identifier">pos</span><span class="plain"> = </span><span class="functiontext">Str::forward</span><span class="plain">(</span><span class="identifier">pos</span><span class="plain">);</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP3_2_3">§3.2.3</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP3_2_3_3"></a><b>§3.2.3.3. </b>And this moves it past the <code class="display"><span class="extract">*</span></code> to point to the <code class="display"><span class="extract">v</span></code> in <code class="display"><span class="extract">int *val;</span></code>:
|
|
</p>
|
|
|
|
|
|
<p class="macrodefinition"><code class="display">
|
|
<<span class="cwebmacrodefn">Move pos past any typographical type modifiers</span> <span class="cwebmacronumber">3.2.3.3</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="reserved">while</span><span class="plain"> ((</span><span class="functiontext">Characters::is_space_or_tab</span><span class="plain">(</span><span class="functiontext">Str::get</span><span class="plain">(</span><span class="identifier">pos</span><span class="plain">))) || (</span><span class="functiontext">Str::get</span><span class="plain">(</span><span class="identifier">pos</span><span class="plain">) == </span><span class="character">'*'</span><span class="plain">) ||</span>
|
|
<span class="plain">(</span><span class="functiontext">Str::get</span><span class="plain">(</span><span class="identifier">pos</span><span class="plain">) == </span><span class="character">'('</span><span class="plain">) || (</span><span class="functiontext">Str::get</span><span class="plain">(</span><span class="identifier">pos</span><span class="plain">) == </span><span class="character">')'</span><span class="plain">)) </span><span class="identifier">pos</span><span class="plain"> = </span><span class="functiontext">Str::forward</span><span class="plain">(</span><span class="identifier">pos</span><span class="plain">);</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP3_2_3">§3.2.3</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP3_2_3_4"></a><b>§3.2.3.4. </b>This then first copies the substring <code class="display"><span class="extract">val;</span></code> into <code class="display"><span class="extract">elname</span></code>, then cuts that
|
|
down to just the identifier characters at the front, i.e., to <code class="display"><span class="extract">val</span></code>.
|
|
</p>
|
|
|
|
|
|
<p class="macrodefinition"><code class="display">
|
|
<<span class="cwebmacrodefn">Copy the element name into elname</span> <span class="cwebmacronumber">3.2.3.4</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="functiontext">Str::substr</span><span class="plain">(</span><span class="identifier">elname</span><span class="plain">, </span><span class="identifier">pos</span><span class="plain">, </span><span class="functiontext">Str::end</span><span class="plain">(</span><span class="identifier">p</span><span class="plain">));</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Regexp::match</span><span class="plain">(&</span><span class="identifier">mr</span><span class="plain">, </span><span class="identifier">elname</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"(%i+)%c*"</span><span class="plain">)) </span><span class="functiontext">Str::copy</span><span class="plain">(</span><span class="identifier">elname</span><span class="plain">, </span><span class="identifier">mr</span><span class="element">.exp</span><span class="plain">[0]);</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP3_2_3">§3.2.3</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP3_2_3_5"></a><b>§3.2.3.5. </b>Now we create an instance of <code class="display"><span class="extract">structure_element</span></code> to record the existence
|
|
of the element <code class="display"><span class="extract">val</span></code>, and add it to the linked list of elements of the
|
|
structure being defined.
|
|
</p>
|
|
|
|
<p class="inwebparagraph">In InC, only, certain element names used often in Inform's source code are
|
|
given mildly special treatment. This doesn't amount to much. <code class="display"><span class="extract">allow_sharing</span></code>
|
|
has no effect on tangling, so it doesn't change the program. It simply
|
|
affects the reports in the woven code about where structures are used.
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">typedef</span><span class="plain"> </span><span class="reserved">struct</span><span class="plain"> </span><span class="reserved">structure_element</span><span class="plain"> {</span>
|
|
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">element_name</span><span class="plain">;</span>
|
|
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">source_line</span><span class="plain"> *</span><span class="identifier">element_created_at</span><span class="plain">;</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">allow_sharing</span><span class="plain">;</span>
|
|
<span class="constant">MEMORY_MANAGEMENT</span>
|
|
<span class="plain">} </span><span class="reserved">structure_element</span><span class="plain">;</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The structure structure_element is accessed in 3/tw and here.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP3_2_3_6"></a><b>§3.2.3.6. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Record the element</span> <span class="cwebmacronumber">3.2.3.6</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="functiontext">Analyser::mark_reserved_word</span><span class="plain">(</span><span class="identifier">L</span><span class="plain">-</span><span class="element">>owning_section</span><span class="plain">, </span><span class="identifier">elname</span><span class="plain">, </span><span class="constant">ELEMENT_COLOUR</span><span class="plain">);</span>
|
|
<span class="reserved">structure_element</span><span class="plain"> *</span><span class="identifier">elt</span><span class="plain"> = </span><span class="identifier">CREATE</span><span class="plain">(</span><span class="reserved">structure_element</span><span class="plain">);</span>
|
|
<span class="identifier">elt</span><span class="plain">-</span><span class="element">>element_name</span><span class="plain"> = </span><span class="functiontext">Str::duplicate</span><span class="plain">(</span><span class="identifier">elname</span><span class="plain">);</span>
|
|
<span class="identifier">elt</span><span class="plain">-</span><span class="element">>allow_sharing</span><span class="plain"> = </span><span class="constant">FALSE</span><span class="plain">;</span>
|
|
<span class="identifier">elt</span><span class="plain">-</span><span class="element">>element_created_at</span><span class="plain"> = </span><span class="identifier">L</span><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Languages::share_element</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">-</span><span class="element">>main_language</span><span class="plain">, </span><span class="identifier">elname</span><span class="plain">)) </span><span class="identifier">elt</span><span class="plain">-</span><span class="element">>allow_sharing</span><span class="plain"> = </span><span class="constant">TRUE</span><span class="plain">;</span>
|
|
<span class="identifier">ADD_TO_LINKED_LIST</span><span class="plain">(</span><span class="identifier">elt</span><span class="plain">, </span><span class="reserved">structure_element</span><span class="plain">, </span><span class="identifier">current_str</span><span class="plain">-</span><span class="element">>elements</span><span class="plain">);</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP3_2_3">§3.2.3</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP3_3"></a><b>§3.3. Structure dependency. </b>We say that S depends on T if <code class="display"><span class="extract">struct S</span></code> has an element whose type is
|
|
<code class="display"><span class="extract">struct T</span></code>. That matters because if so then <code class="display"><span class="extract">struct T</span></code> has to be defined
|
|
before <code class="display"><span class="extract">struct S</span></code> in the tangled output.
|
|
</p>
|
|
|
|
<p class="inwebparagraph">It's important to note that <code class="display"><span class="extract">struct S</span></code> merely having a member of type
|
|
<code class="display"><span class="extract">struct *T</span></code> does not create a dependency. In the code below, because <code class="display"><span class="extract">%i</span></code>
|
|
matches only identifier characters and <code class="display"><span class="extract">*</span></code> is not one of those, a line like
|
|
</p>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="plain"> struct fruit *often_confused_with;</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph">will not trip the switch here.
|
|
</p>
|
|
|
|
|
|
<p class="macrodefinition"><code class="display">
|
|
<<span class="cwebmacrodefn">Work out which structs contain which others</span> <span class="cwebmacronumber">3.3</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="reserved">c_structure</span><span class="plain"> *</span><span class="identifier">current_str</span><span class="plain">;</span>
|
|
<span class="identifier">LOOP_OVER</span><span class="plain">(</span><span class="identifier">current_str</span><span class="plain">, </span><span class="reserved">c_structure</span><span class="plain">) {</span>
|
|
<span class="reserved">for</span><span class="plain"> (</span><span class="reserved">source_line</span><span class="plain"> *</span><span class="identifier">L</span><span class="plain"> = </span><span class="identifier">current_str</span><span class="plain">-</span><span class="element">>typedef_begins</span><span class="plain">;</span>
|
|
<span class="plain">((</span><span class="identifier">L</span><span class="plain">) && (</span><span class="identifier">L</span><span class="plain"> != </span><span class="identifier">current_str</span><span class="plain">-</span><span class="element">>typedef_ends</span><span class="plain">));</span>
|
|
<span class="identifier">L</span><span class="plain"> = </span><span class="identifier">L</span><span class="plain">-</span><span class="element">>next_line</span><span class="plain">) {</span>
|
|
<span class="reserved">match_results</span><span class="plain"> </span><span class="identifier">mr</span><span class="plain"> = </span><span class="functiontext">Regexp::create_mr</span><span class="plain">();</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Regexp::match</span><span class="plain">(&</span><span class="identifier">mr</span><span class="plain">, </span><span class="identifier">L</span><span class="plain">-</span><span class="element">>text</span><span class="plain">, </span><span class="identifier">L</span><span class="string">" struct (%i+) %i%c*"</span><span class="plain">))</span>
|
|
<<span class="cwebmacro">One structure appears to contain a copy of another one</span> <span class="cwebmacronumber">3.3.1</span>><span class="plain">;</span>
|
|
<span class="functiontext">Regexp::dispose_of</span><span class="plain">(&</span><span class="identifier">mr</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP3">§3</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP3_3_1"></a><b>§3.3.1. </b><code class="display">
|
|
<<span class="cwebmacrodefn">One structure appears to contain a copy of another one</span> <span class="cwebmacronumber">3.3.1</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">used_structure</span><span class="plain"> = </span><span class="identifier">mr</span><span class="element">.exp</span><span class="plain">[0];</span>
|
|
<span class="reserved">c_structure</span><span class="plain"> *</span><span class="identifier">str</span><span class="plain">;</span>
|
|
<span class="identifier">LOOP_OVER_LINKED_LIST</span><span class="plain">(</span><span class="identifier">str</span><span class="plain">, </span><span class="reserved">c_structure</span><span class="plain">, </span><span class="identifier">W</span><span class="plain">-</span><span class="element">>c_structures</span><span class="plain">)</span>
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">str</span><span class="plain"> != </span><span class="identifier">current_str</span><span class="plain">) &&</span>
|
|
<span class="plain">(</span><span class="functiontext">Str::eq</span><span class="plain">(</span><span class="identifier">used_structure</span><span class="plain">, </span><span class="identifier">str</span><span class="plain">-</span><span class="element">>structure_name</span><span class="plain">)))</span>
|
|
<span class="identifier">ADD_TO_LINKED_LIST</span><span class="plain">(</span><span class="identifier">str</span><span class="plain">, </span><span class="reserved">c_structure</span><span class="plain">, </span><span class="identifier">current_str</span><span class="plain">-</span><span class="element">>incorporates</span><span class="plain">);</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP3_3">§3.3</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP3_4"></a><b>§3.4. Functions. </b>Second round: we recognise a C function as being a line which takes the form
|
|
</p>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="plain">type identifier(args...</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph">where we parse <code class="display"><span class="extract">type</span></code> only minimally. In InC (only), the identifier can
|
|
contain namespace dividers written <code class="display"><span class="extract">::</span></code>. Function declarations, we will assume,
|
|
always begin on column 1 of their source files, and we expect them to take
|
|
modern ANSI C style, not the long-deprecated late 1970s C style.
|
|
</p>
|
|
|
|
|
|
<p class="macrodefinition"><code class="display">
|
|
<<span class="cwebmacrodefn">Look for a function definition on this line</span> <span class="cwebmacronumber">3.4</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="reserved">if</span><span class="plain"> (!(</span><span class="functiontext">Characters::is_space_or_tab</span><span class="plain">(</span><span class="functiontext">Str::get_first_char</span><span class="plain">(</span><span class="identifier">L</span><span class="plain">-</span><span class="element">>text</span><span class="plain">)))) {</span>
|
|
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">qualifiers</span><span class="plain">);</span>
|
|
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">modified</span><span class="plain">);</span>
|
|
<span class="functiontext">Str::copy</span><span class="plain">(</span><span class="identifier">modified</span><span class="plain">, </span><span class="identifier">L</span><span class="plain">-</span><span class="element">>text</span><span class="plain">);</span>
|
|
<<span class="cwebmacro">Parse past any type modifiers</span> <span class="cwebmacronumber">3.4.1</span>><span class="plain">;</span>
|
|
<span class="reserved">match_results</span><span class="plain"> </span><span class="identifier">mr</span><span class="plain"> = </span><span class="functiontext">Regexp::create_mr</span><span class="plain">();</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Regexp::match</span><span class="plain">(&</span><span class="identifier">mr</span><span class="plain">, </span><span class="identifier">modified</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"(%i+) (%**)(%i+)%((%c*)"</span><span class="plain">)) {</span>
|
|
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">ftype</span><span class="plain">); </span><span class="functiontext">Str::copy</span><span class="plain">(</span><span class="identifier">ftype</span><span class="plain">, </span><span class="identifier">mr</span><span class="element">.exp</span><span class="plain">[0]);</span>
|
|
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">asts</span><span class="plain">); </span><span class="functiontext">Str::copy</span><span class="plain">(</span><span class="identifier">asts</span><span class="plain">, </span><span class="identifier">mr</span><span class="element">.exp</span><span class="plain">[1]);</span>
|
|
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">fname</span><span class="plain">); </span><span class="functiontext">Str::copy</span><span class="plain">(</span><span class="identifier">fname</span><span class="plain">, </span><span class="identifier">mr</span><span class="element">.exp</span><span class="plain">[2]);</span>
|
|
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">arguments</span><span class="plain">); </span><span class="functiontext">Str::copy</span><span class="plain">(</span><span class="identifier">arguments</span><span class="plain">, </span><span class="identifier">mr</span><span class="element">.exp</span><span class="plain">[3]);</span>
|
|
<<span class="cwebmacro">A function definition was found</span> <span class="cwebmacronumber">3.4.2</span>><span class="plain">;</span>
|
|
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">ftype</span><span class="plain">);</span>
|
|
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">asts</span><span class="plain">);</span>
|
|
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">fname</span><span class="plain">);</span>
|
|
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">arguments</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">qualifiers</span><span class="plain">);</span>
|
|
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">modified</span><span class="plain">);</span>
|
|
<span class="functiontext">Regexp::dispose_of</span><span class="plain">(&</span><span class="identifier">mr</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP3">§3</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP3_4_1"></a><b>§3.4.1. </b>C has a whole soup of reserved words applying to types, but most of them
|
|
can't apply to the return type of a function. We do, however, iterate so that
|
|
forms like <code class="display"><span class="extract">static long long int</span></code> will work.
|
|
</p>
|
|
|
|
|
|
<p class="macrodefinition"><code class="display">
|
|
<<span class="cwebmacrodefn">Parse past any type modifiers</span> <span class="cwebmacronumber">3.4.1</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="identifier">wchar_t</span><span class="plain"> *</span><span class="identifier">modifier_patterns</span><span class="plain">[] = {</span>
|
|
<span class="identifier">L</span><span class="string">"(signed )(%C%c*)"</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"(unsigned )(%C%c*)"</span><span class="plain">,</span>
|
|
<span class="identifier">L</span><span class="string">"(short )(%C%c*)"</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"(long )(%C%c*)"</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"(static )(%C%c*)"</span><span class="plain">, </span><span class="identifier">NULL</span><span class="plain"> };</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">seek_modifiers</span><span class="plain"> = </span><span class="constant">TRUE</span><span class="plain">;</span>
|
|
<span class="reserved">while</span><span class="plain"> (</span><span class="identifier">seek_modifiers</span><span class="plain">) {</span>
|
|
<span class="identifier">seek_modifiers</span><span class="plain"> = </span><span class="constant">FALSE</span><span class="plain">;</span>
|
|
<span class="reserved">match_results</span><span class="plain"> </span><span class="identifier">mr</span><span class="plain"> = </span><span class="functiontext">Regexp::create_mr</span><span class="plain">();</span>
|
|
<span class="reserved">for</span><span class="plain"> (</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">i</span><span class="plain"> = 0; </span><span class="identifier">modifier_patterns</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">]; </span><span class="identifier">i</span><span class="plain">++)</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Regexp::match</span><span class="plain">(&</span><span class="identifier">mr</span><span class="plain">, </span><span class="identifier">modified</span><span class="plain">, </span><span class="identifier">modifier_patterns</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">])) {</span>
|
|
<span class="functiontext">Str::concatenate</span><span class="plain">(</span><span class="identifier">qualifiers</span><span class="plain">, </span><span class="identifier">mr</span><span class="element">.exp</span><span class="plain">[0]);</span>
|
|
<span class="functiontext">Str::copy</span><span class="plain">(</span><span class="identifier">modified</span><span class="plain">, </span><span class="identifier">mr</span><span class="element">.exp</span><span class="plain">[1]);</span>
|
|
<span class="identifier">seek_modifiers</span><span class="plain"> = </span><span class="constant">TRUE</span><span class="plain">; </span><span class="reserved">break</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
<span class="functiontext">Regexp::dispose_of</span><span class="plain">(&</span><span class="identifier">mr</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP3_4">§3.4</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP3_4_2"></a><b>§3.4.2. </b><code class="display">
|
|
<<span class="cwebmacrodefn">A function definition was found</span> <span class="cwebmacronumber">3.4.2</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<<span class="cwebmacro">Soak up further arguments from continuation lines after the declaration</span> <span class="cwebmacronumber">3.4.2.1</span>><span class="plain">;</span>
|
|
<span class="functiontext">Analyser::mark_reserved_word</span><span class="plain">(</span><span class="identifier">L</span><span class="plain">-</span><span class="element">>owning_section</span><span class="plain">, </span><span class="identifier">fname</span><span class="plain">, </span><span class="constant">FUNCTION_COLOUR</span><span class="plain">);</span>
|
|
<span class="reserved">function</span><span class="plain"> *</span><span class="identifier">fn</span><span class="plain"> = </span><span class="identifier">CREATE</span><span class="plain">(</span><span class="reserved">function</span><span class="plain">);</span>
|
|
<<span class="cwebmacro">Initialise the function structure</span> <span class="cwebmacronumber">3.4.2.3</span>><span class="plain">;</span>
|
|
<<span class="cwebmacro">Add the function to its paragraph and line</span> <span class="cwebmacronumber">3.4.2.4</span>><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">W</span><span class="plain">-</span><span class="element">>main_language</span><span class="plain">-</span><span class="element">>supports_namespaces</span><span class="plain">)</span>
|
|
<<span class="cwebmacro">Check that the function has its namespace correctly declared</span> <span class="cwebmacronumber">3.4.2.5</span>><span class="plain">;</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP3_4">§3.4</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP3_4_2_1"></a><b>§3.4.2.1. </b>In some cases the function's declaration runs over several lines:
|
|
</p>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="plain">void World::Subjects::make_adj_const_domain(inference_subject *infs,</span>
|
|
<span class="plain"> instance *nc, property *prn) {</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph">Having read the first line, <code class="display"><span class="extract">arguments</span></code> would contain <code class="display"><span class="extract">inference_subject *infs,</span></code>
|
|
and would thus be incomplete. We continue across subsequent lines until we
|
|
reach an open brace <code class="display"><span class="extract">{</span></code>.
|
|
</p>
|
|
|
|
|
|
<pre class="definitions">
|
|
<span class="definitionkeyword">define</span> <span class="constant">MAX_ARG_LINES</span><span class="plain"> 8 </span> <span class="comment">maximum number of lines over which a function's header can extend</span>
|
|
</pre>
|
|
|
|
<p class="macrodefinition"><code class="display">
|
|
<<span class="cwebmacrodefn">Soak up further arguments from continuation lines after the declaration</span> <span class="cwebmacronumber">3.4.2.1</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="reserved">source_line</span><span class="plain"> *</span><span class="identifier">AL</span><span class="plain"> = </span><span class="identifier">L</span><span class="plain">;</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">arg_lc</span><span class="plain"> = 1;</span>
|
|
<span class="reserved">while</span><span class="plain"> ((</span><span class="identifier">AL</span><span class="plain">) && (</span><span class="identifier">arg_lc</span><span class="plain"> <= </span><span class="constant">MAX_ARG_LINES</span><span class="plain">) && (</span><span class="functiontext">Regexp::find_open_brace</span><span class="plain">(</span><span class="identifier">arguments</span><span class="plain">) == -1)) {</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">AL</span><span class="plain">-</span><span class="element">>next_line</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) {</span>
|
|
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">err_mess</span><span class="plain">);</span>
|
|
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">err_mess</span><span class="plain">, </span><span class="string">"Function '%S' has a malformed declaration"</span><span class="plain">, </span><span class="identifier">fname</span><span class="plain">);</span>
|
|
<span class="functiontext">Main::error_in_web</span><span class="plain">(</span><span class="identifier">err_mess</span><span class="plain">, </span><span class="identifier">L</span><span class="plain">);</span>
|
|
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">err_mess</span><span class="plain">);</span>
|
|
<span class="reserved">break</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
<span class="identifier">AL</span><span class="plain"> = </span><span class="identifier">AL</span><span class="plain">-</span><span class="element">>next_line</span><span class="plain">;</span>
|
|
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">arguments</span><span class="plain">, </span><span class="string">" %S"</span><span class="plain">, </span><span class="identifier">AL</span><span class="plain">-</span><span class="element">>text</span><span class="plain">);</span>
|
|
<span class="identifier">arg_lc</span><span class="plain">++;</span>
|
|
<span class="plain">}</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">n</span><span class="plain"> = </span><span class="functiontext">Regexp::find_open_brace</span><span class="plain">(</span><span class="identifier">arguments</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">n</span><span class="plain"> >= 0) </span><span class="functiontext">Str::truncate</span><span class="plain">(</span><span class="identifier">arguments</span><span class="plain">, </span><span class="identifier">n</span><span class="plain">);</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP3_4_2">§3.4.2</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP3_4_2_2"></a><b>§3.4.2.2. </b>Each function definition found results in one of these structures being made:
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">typedef</span><span class="plain"> </span><span class="reserved">struct</span><span class="plain"> </span><span class="reserved">function</span><span class="plain"> {</span>
|
|
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">function_name</span><span class="plain">; </span> <span class="comment">e.g., <code class="display"><span class="extract">"cultivate"</span></code></span>
|
|
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">function_type</span><span class="plain">; </span> <span class="comment">e.g., <code class="display"><span class="extract">"tree *"</span></code></span>
|
|
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">function_arguments</span><span class="plain">; </span> <span class="comment">e.g., <code class="display"><span class="extract">"int rainfall)"</span></code>: note <code class="display"><span class="extract">)</span></code></span>
|
|
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">source_line</span><span class="plain"> *</span><span class="identifier">function_header_at</span><span class="plain">; </span> <span class="comment">where the first line of the header begins</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">within_namespace</span><span class="plain">; </span> <span class="comment">written using InC namespace dividers</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">called_from_other_sections</span><span class="plain">;</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">call_freely</span><span class="plain">;</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">no_conditionals</span><span class="plain">;</span>
|
|
<span class="reserved">struct</span><span class="plain"> </span><span class="reserved">source_line</span><span class="plain"> *</span><span class="identifier">within_conditionals</span><span class="plain">[</span><span class="constant">MAX_CONDITIONAL_COMPILATION_STACK</span><span class="plain">];</span>
|
|
<span class="constant">MEMORY_MANAGEMENT</span>
|
|
<span class="plain">} </span><span class="reserved">function</span><span class="plain">;</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The structure function is accessed in 3/tw and here.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP3_4_2_3"></a><b>§3.4.2.3. </b>Note that we take a snapshot of the conditional compilation stack as
|
|
part of the function structure. We'll need it when predeclaring the function.
|
|
</p>
|
|
|
|
|
|
<p class="macrodefinition"><code class="display">
|
|
<<span class="cwebmacrodefn">Initialise the function structure</span> <span class="cwebmacronumber">3.4.2.3</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="identifier">fn</span><span class="plain">-</span><span class="element">>function_name</span><span class="plain"> = </span><span class="functiontext">Str::duplicate</span><span class="plain">(</span><span class="identifier">fname</span><span class="plain">);</span>
|
|
<span class="identifier">fn</span><span class="plain">-</span><span class="element">>function_arguments</span><span class="plain"> = </span><span class="functiontext">Str::duplicate</span><span class="plain">(</span><span class="identifier">arguments</span><span class="plain">);</span>
|
|
<span class="identifier">fn</span><span class="plain">-</span><span class="element">>function_type</span><span class="plain"> = </span><span class="functiontext">Str::new</span><span class="plain">();</span>
|
|
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">fn</span><span class="plain">-</span><span class="element">>function_type</span><span class="plain">, </span><span class="string">"%S%S %S"</span><span class="plain">, </span><span class="identifier">qualifiers</span><span class="plain">, </span><span class="identifier">ftype</span><span class="plain">, </span><span class="identifier">asts</span><span class="plain">);</span>
|
|
<span class="identifier">fn</span><span class="plain">-</span><span class="element">>within_namespace</span><span class="plain"> = </span><span class="constant">FALSE</span><span class="plain">;</span>
|
|
<span class="identifier">fn</span><span class="plain">-</span><span class="element">>called_from_other_sections</span><span class="plain"> = </span><span class="constant">FALSE</span><span class="plain">;</span>
|
|
<span class="identifier">fn</span><span class="plain">-</span><span class="element">>call_freely</span><span class="plain"> = </span><span class="constant">FALSE</span><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="functiontext">Str::eq_wide_string</span><span class="plain">(</span><span class="identifier">fn</span><span class="plain">-</span><span class="element">>function_name</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"isdigit"</span><span class="plain">)) &&</span>
|
|
<span class="plain">(</span><span class="identifier">W</span><span class="plain">-</span><span class="element">>main_language</span><span class="plain">-</span><span class="element">>supports_namespaces</span><span class="plain">))</span>
|
|
<span class="identifier">fn</span><span class="plain">-</span><span class="element">>call_freely</span><span class="plain"> = </span><span class="constant">TRUE</span><span class="plain">;</span>
|
|
<span class="identifier">fn</span><span class="plain">-</span><span class="element">>function_header_at</span><span class="plain"> = </span><span class="identifier">L</span><span class="plain">;</span>
|
|
|
|
<span class="identifier">fn</span><span class="plain">-</span><span class="element">>no_conditionals</span><span class="plain"> = </span><span class="identifier">cc_sp</span><span class="plain">;</span>
|
|
<span class="reserved">for</span><span class="plain"> (</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">i</span><span class="plain">=0; </span><span class="identifier">i</span><span class="plain"><</span><span class="identifier">cc_sp</span><span class="plain">; </span><span class="identifier">i</span><span class="plain">++) </span><span class="identifier">fn</span><span class="plain">-</span><span class="element">>within_conditionals</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">] = </span><span class="identifier">cc_stack</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">];</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP3_4_2">§3.4.2</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP3_4_2_4"></a><b>§3.4.2.4. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Add the function to its paragraph and line</span> <span class="cwebmacronumber">3.4.2.4</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="reserved">paragraph</span><span class="plain"> *</span><span class="identifier">P</span><span class="plain"> = </span><span class="identifier">L</span><span class="plain">-</span><span class="element">>owning_paragraph</span><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">P</span><span class="plain">) </span><span class="identifier">ADD_TO_LINKED_LIST</span><span class="plain">(</span><span class="identifier">fn</span><span class="plain">, </span><span class="reserved">function</span><span class="plain">, </span><span class="identifier">P</span><span class="plain">-</span><span class="element">>functions</span><span class="plain">);</span>
|
|
<span class="identifier">L</span><span class="plain">-</span><span class="element">>function_defined</span><span class="plain"> = </span><span class="identifier">fn</span><span class="plain">;</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP3_4_2">§3.4.2</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP3_4_2_5"></a><b>§3.4.2.5. </b><code class="display">
|
|
<<span class="cwebmacrodefn">Check that the function has its namespace correctly declared</span> <span class="cwebmacronumber">3.4.2.5</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">declared_namespace</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="reserved">match_results</span><span class="plain"> </span><span class="identifier">mr</span><span class="plain"> = </span><span class="functiontext">Regexp::create_mr</span><span class="plain">();</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Regexp::match</span><span class="plain">(&</span><span class="identifier">mr</span><span class="plain">, </span><span class="identifier">fname</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"(%c+::)%c*"</span><span class="plain">)) {</span>
|
|
<span class="identifier">declared_namespace</span><span class="plain"> = </span><span class="identifier">mr</span><span class="element">.exp</span><span class="plain">[0];</span>
|
|
<span class="identifier">fn</span><span class="plain">-</span><span class="element">>within_namespace</span><span class="plain"> = </span><span class="constant">TRUE</span><span class="plain">;</span>
|
|
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> </span><span class="reserved">if</span><span class="plain"> ((</span><span class="functiontext">Str::eq_wide_string</span><span class="plain">(</span><span class="identifier">fname</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"main"</span><span class="plain">)) && (</span><span class="functiontext">Str::eq_wide_string</span><span class="plain">(</span><span class="identifier">S</span><span class="plain">-</span><span class="element">>sect_namespace</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"Main::"</span><span class="plain">)))</span>
|
|
<span class="identifier">declared_namespace</span><span class="plain"> = </span><span class="identifier">I</span><span class="string">"Main::"</span><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="functiontext">Str::ne</span><span class="plain">(</span><span class="identifier">declared_namespace</span><span class="plain">, </span><span class="identifier">S</span><span class="plain">-</span><span class="element">>sect_namespace</span><span class="plain">)) &&</span>
|
|
<span class="plain">(</span><span class="identifier">L</span><span class="plain">-</span><span class="element">>owning_paragraph</span><span class="plain">-</span><span class="element">>placed_very_early</span><span class="plain"> == </span><span class="constant">FALSE</span><span class="plain">)) {</span>
|
|
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">err_mess</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Str::len</span><span class="plain">(</span><span class="identifier">declared_namespace</span><span class="plain">) == 0)</span>
|
|
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">err_mess</span><span class="plain">, </span><span class="string">"Function '%S' should have namespace prefix '%S'"</span><span class="plain">,</span>
|
|
<span class="identifier">fname</span><span class="plain">, </span><span class="identifier">S</span><span class="plain">-</span><span class="element">>sect_namespace</span><span class="plain">);</span>
|
|
<span class="reserved">else</span><span class="plain"> </span><span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Str::len</span><span class="plain">(</span><span class="identifier">S</span><span class="plain">-</span><span class="element">>sect_namespace</span><span class="plain">) == 0)</span>
|
|
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">err_mess</span><span class="plain">, </span><span class="string">"Function '%S' declared in a section with no namespace"</span><span class="plain">,</span>
|
|
<span class="identifier">fname</span><span class="plain">);</span>
|
|
<span class="reserved">else</span>
|
|
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">err_mess</span><span class="plain">, </span><span class="string">"Function '%S' declared in a section with the wrong namespace '%S'"</span><span class="plain">,</span>
|
|
<span class="identifier">fname</span><span class="plain">, </span><span class="identifier">S</span><span class="plain">-</span><span class="element">>sect_namespace</span><span class="plain">);</span>
|
|
<span class="functiontext">Main::error_in_web</span><span class="plain">(</span><span class="identifier">err_mess</span><span class="plain">, </span><span class="identifier">L</span><span class="plain">);</span>
|
|
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">err_mess</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
<span class="functiontext">Regexp::dispose_of</span><span class="plain">(&</span><span class="identifier">mr</span><span class="plain">);</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP3_4_2">§3.4.2</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP4"></a><b>§4. </b>The following
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">c_structure</span><span class="plain"> *</span><span class="functiontext">CLike::find_structure</span><span class="plain">(</span><span class="reserved">web</span><span class="plain"> *</span><span class="identifier">W</span><span class="plain">, </span><span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">name</span><span class="plain">) {</span>
|
|
<span class="reserved">c_structure</span><span class="plain"> *</span><span class="identifier">str</span><span class="plain">;</span>
|
|
<span class="identifier">LOOP_OVER_LINKED_LIST</span><span class="plain">(</span><span class="identifier">str</span><span class="plain">, </span><span class="reserved">c_structure</span><span class="plain">, </span><span class="identifier">W</span><span class="plain">-</span><span class="element">>c_structures</span><span class="plain">)</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Str::eq</span><span class="plain">(</span><span class="identifier">name</span><span class="plain">, </span><span class="identifier">str</span><span class="plain">-</span><span class="element">>structure_name</span><span class="plain">))</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">str</span><span class="plain">;</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function CLike::find_structure appears nowhere else.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP5"></a><b>§5. Subcategorisation. </b>The following is called after the parser gives every line in the web a
|
|
category; we can, if we wish, change that for a more exotic one. We simply
|
|
look for a <code class="display"><span class="extract">#include</span></code> of one of the ANSI C standard libraries.
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">CLike::subcategorise_code</span><span class="plain">(</span><span class="reserved">programming_language</span><span class="plain"> *</span><span class="identifier">self</span><span class="plain">, </span><span class="reserved">source_line</span><span class="plain"> *</span><span class="identifier">L</span><span class="plain">) {</span>
|
|
<span class="reserved">match_results</span><span class="plain"> </span><span class="identifier">mr</span><span class="plain"> = </span><span class="functiontext">Regexp::create_mr</span><span class="plain">();</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Regexp::match</span><span class="plain">(&</span><span class="identifier">mr</span><span class="plain">, </span><span class="identifier">L</span><span class="plain">-</span><span class="element">>text</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"#include <(%C+)>%c*"</span><span class="plain">)) {</span>
|
|
<span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">library_file</span><span class="plain"> = </span><span class="identifier">mr</span><span class="element">.exp</span><span class="plain">[0];</span>
|
|
<span class="identifier">wchar_t</span><span class="plain"> *</span><span class="identifier">ansi_libs</span><span class="plain">[] = {</span>
|
|
<span class="identifier">L</span><span class="string">"assert.h"</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"ctype.h"</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"errno.h"</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"float.h"</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"limits.h"</span><span class="plain">,</span>
|
|
<span class="identifier">L</span><span class="string">"locale.h"</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"math.h"</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"setjmp.h"</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"signal.h"</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"stdarg.h"</span><span class="plain">,</span>
|
|
<span class="identifier">L</span><span class="string">"stddef.h"</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"stdio.h"</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"stdlib.h"</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"string.h"</span><span class="plain">, </span><span class="identifier">L</span><span class="string">"time.h"</span><span class="plain">,</span>
|
|
<span class="identifier">NULL</span>
|
|
<span class="plain">};</span>
|
|
<span class="reserved">for</span><span class="plain"> (</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">j</span><span class="plain"> = 0; </span><span class="identifier">ansi_libs</span><span class="plain">[</span><span class="identifier">j</span><span class="plain">]; </span><span class="identifier">j</span><span class="plain">++)</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Str::eq_wide_string</span><span class="plain">(</span><span class="identifier">library_file</span><span class="plain">, </span><span class="identifier">ansi_libs</span><span class="plain">[</span><span class="identifier">j</span><span class="plain">]))</span>
|
|
<span class="identifier">L</span><span class="plain">-</span><span class="element">>category</span><span class="plain"> = </span><span class="constant">C_LIBRARY_INCLUDE_LCAT</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
<span class="functiontext">Regexp::dispose_of</span><span class="plain">(&</span><span class="identifier">mr</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function CLike::subcategorise_code is used in <a href="#SP2">§2</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP6"></a><b>§6. Tangling extras. </b>The "shebang" routine for a language is called to add anything it wants to
|
|
at the very top of the tangled code. (For a scripting language such as
|
|
Perl or Python, that might be a shebang: hence the name.)
|
|
</p>
|
|
|
|
<p class="inwebparagraph">But we will use it to defime the constant <code class="display"><span class="extract">PLATFORM_POSIX</span></code> everywhere except
|
|
Windows. This needs to happen right at the top, because the "very early
|
|
code" may contain material conditional on whether it is defined.
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">CLike::shebang</span><span class="plain">(</span><span class="reserved">programming_language</span><span class="plain"> *</span><span class="identifier">self</span><span class="plain">, </span><span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">OUT</span><span class="plain">, </span><span class="reserved">web</span><span class="plain"> *</span><span class="identifier">W</span><span class="plain">, </span><span class="reserved">tangle_target</span><span class="plain"> *</span><span class="identifier">target</span><span class="plain">) {</span>
|
|
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"#ifndef PLATFORM_WINDOWS\</span><span class="plain">n</span><span class="string">"</span><span class="plain">);</span>
|
|
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"#define PLATFORM_POSIX\</span><span class="plain">n</span><span class="string">"</span><span class="plain">);</span>
|
|
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"#endif\</span><span class="plain">n</span><span class="string">"</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function CLike::shebang is used in <a href="#SP2">§2</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP7"></a><b>§7. </b>"Additional early matter" is used for the inclusions of the ANSI library
|
|
files. We need to do that early, because otherwise types declared in them
|
|
(such as <code class="display"><span class="extract">FILE</span></code>) won't exist in time for the structure definitions we will
|
|
be tangling next.
|
|
</p>
|
|
|
|
<p class="inwebparagraph">It might seem reasonable to move all <code class="display"><span class="extract">#include</span></code> files up front this way,
|
|
not just the ANSI ones. But that would defeat any conditional compilation
|
|
around the inclusions; which Inform (for instance) needs in order to make
|
|
platform-specific details to handle directories without POSIX in Windows.
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">CLike::additional_early_matter</span><span class="plain">(</span><span class="reserved">programming_language</span><span class="plain"> *</span><span class="identifier">self</span><span class="plain">, </span><span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">OUT</span><span class="plain">, </span><span class="reserved">web</span><span class="plain"> *</span><span class="identifier">W</span><span class="plain">, </span><span class="reserved">tangle_target</span><span class="plain"> *</span><span class="identifier">target</span><span class="plain">) {</span>
|
|
<span class="reserved">chapter</span><span class="plain"> *</span><span class="identifier">C</span><span class="plain">;</span>
|
|
<span class="reserved">section</span><span class="plain"> *</span><span class="identifier">S</span><span class="plain">;</span>
|
|
<span class="identifier">LOOP_WITHIN_TANGLE</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">, </span><span class="identifier">S</span><span class="plain">, </span><span class="identifier">target</span><span class="plain">)</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">L</span><span class="plain">-</span><span class="element">>category</span><span class="plain"> == </span><span class="constant">C_LIBRARY_INCLUDE_LCAT</span><span class="plain">) {</span>
|
|
<span class="functiontext">Tags::open_ifdefs</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">L</span><span class="plain">-</span><span class="element">>owning_paragraph</span><span class="plain">);</span>
|
|
<span class="functiontext">Tangler::tangle_code</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">L</span><span class="plain">-</span><span class="element">>text</span><span class="plain">, </span><span class="identifier">S</span><span class="plain">, </span><span class="identifier">L</span><span class="plain">);</span>
|
|
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"\</span><span class="plain">n</span><span class="string">"</span><span class="plain">);</span>
|
|
<span class="functiontext">Tags::close_ifdefs</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">L</span><span class="plain">-</span><span class="element">>owning_paragraph</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function CLike::additional_early_matter is used in <a href="#SP2">§2</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP8"></a><b>§8. </b></p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">CLike::start_definition</span><span class="plain">(</span><span class="reserved">programming_language</span><span class="plain"> *</span><span class="identifier">self</span><span class="plain">, </span><span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">OUT</span><span class="plain">, </span><span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">term</span><span class="plain">, </span><span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">start</span><span class="plain">, </span><span class="reserved">section</span><span class="plain"> *</span><span class="identifier">S</span><span class="plain">, </span><span class="reserved">source_line</span><span class="plain"> *</span><span class="identifier">L</span><span class="plain">) {</span>
|
|
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"#define %S "</span><span class="plain">, </span><span class="identifier">term</span><span class="plain">);</span>
|
|
<span class="functiontext">Tangler::tangle_code</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">start</span><span class="plain">, </span><span class="identifier">S</span><span class="plain">, </span><span class="identifier">L</span><span class="plain">);</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="constant">TRUE</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">CLike::prolong_definition</span><span class="plain">(</span><span class="reserved">programming_language</span><span class="plain"> *</span><span class="identifier">self</span><span class="plain">, </span><span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">OUT</span><span class="plain">, </span><span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">more</span><span class="plain">, </span><span class="reserved">section</span><span class="plain"> *</span><span class="identifier">S</span><span class="plain">, </span><span class="reserved">source_line</span><span class="plain"> *</span><span class="identifier">L</span><span class="plain">) {</span>
|
|
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"\</span><span class="plain">\</span><span class="string">\</span><span class="plain">n</span><span class="string"> "</span><span class="plain">);</span>
|
|
<span class="functiontext">Tangler::tangle_code</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">more</span><span class="plain">, </span><span class="identifier">S</span><span class="plain">, </span><span class="identifier">L</span><span class="plain">);</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="constant">TRUE</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">CLike::end_definition</span><span class="plain">(</span><span class="reserved">programming_language</span><span class="plain"> *</span><span class="identifier">self</span><span class="plain">, </span><span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">OUT</span><span class="plain">, </span><span class="reserved">section</span><span class="plain"> *</span><span class="identifier">S</span><span class="plain">, </span><span class="reserved">source_line</span><span class="plain"> *</span><span class="identifier">L</span><span class="plain">) {</span>
|
|
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"\</span><span class="plain">n</span><span class="string">"</span><span class="plain">);</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="constant">TRUE</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function CLike::start_definition is used in <a href="#SP2">§2</a>.</p>
|
|
|
|
<p class="endnote">The function CLike::prolong_definition is used in <a href="#SP2">§2</a>.</p>
|
|
|
|
<p class="endnote">The function CLike::end_definition is used in <a href="#SP2">§2</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP9"></a><b>§9. Tangling predeclarations. </b>This is where a language gets the chance to tangle predeclarations, early
|
|
on in the file. We use it first for the structures, and then the functions —
|
|
in that order since the function types likely involve the typedef names for the
|
|
structures.
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">CLike::additional_predeclarations</span><span class="plain">(</span><span class="reserved">programming_language</span><span class="plain"> *</span><span class="identifier">self</span><span class="plain">, </span><span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">OUT</span><span class="plain">, </span><span class="reserved">web</span><span class="plain"> *</span><span class="identifier">W</span><span class="plain">) {</span>
|
|
<<span class="cwebmacro">Predeclare the structures in a well-founded order</span> <span class="cwebmacronumber">9.2</span>><span class="plain">;</span>
|
|
<<span class="cwebmacro">Predeclare simple typedefs</span> <span class="cwebmacronumber">9.1</span>><span class="plain">;</span>
|
|
<<span class="cwebmacro">Predeclare the functions</span> <span class="cwebmacronumber">9.4</span>><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function CLike::additional_predeclarations is used in <a href="#SP2">§2</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP9_1"></a><b>§9.1. </b>A "simple typedef" here means one that is aliasing something other than
|
|
a structure: for example <code class="display"><span class="extract">typedef unsigned int uint;</span></code> would be a simple typedef.
|
|
</p>
|
|
|
|
|
|
<p class="macrodefinition"><code class="display">
|
|
<<span class="cwebmacrodefn">Predeclare simple typedefs</span> <span class="cwebmacronumber">9.1</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="reserved">chapter</span><span class="plain"> *</span><span class="identifier">C</span><span class="plain">;</span>
|
|
<span class="reserved">section</span><span class="plain"> *</span><span class="identifier">S</span><span class="plain">;</span>
|
|
<span class="identifier">LOOP_WITHIN_TANGLE</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">, </span><span class="identifier">S</span><span class="plain">, </span><span class="functiontext">Tangler::primary_target</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">))</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">L</span><span class="plain">-</span><span class="element">>category</span><span class="plain"> == </span><span class="constant">TYPEDEF_LCAT</span><span class="plain">) {</span>
|
|
<span class="functiontext">Tags::open_ifdefs</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">L</span><span class="plain">-</span><span class="element">>owning_paragraph</span><span class="plain">);</span>
|
|
<span class="functiontext">Languages::tangle_code</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">W</span><span class="plain">-</span><span class="element">>main_language</span><span class="plain">, </span><span class="identifier">L</span><span class="plain">-</span><span class="element">>text</span><span class="plain">);</span>
|
|
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"\</span><span class="plain">n</span><span class="string">"</span><span class="plain">);</span>
|
|
<span class="functiontext">Tags::close_ifdefs</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">L</span><span class="plain">-</span><span class="element">>owning_paragraph</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP9">§9</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP9_2"></a><b>§9.2. </b>It's easy enough to make sure structures are tangled so that inner ones
|
|
precede outer, but we need to be careful to be terminating if the source
|
|
code we're given is not well founded because of an error by its programmer:
|
|
for example, that structure A contains B contains C contains A. We do this
|
|
with the <code class="display"><span class="extract">tangled</span></code> flag, which is <code class="display"><span class="extract">FALSE</span></code> if a structure hasn't been
|
|
started yet, <code class="display"><span class="extract">NOT_APPLICABLE</span></code> if it's in progress, and <code class="display"><span class="extract">TRUE</span></code> if it's
|
|
finished.
|
|
</p>
|
|
|
|
|
|
<p class="macrodefinition"><code class="display">
|
|
<<span class="cwebmacrodefn">Predeclare the structures in a well-founded order</span> <span class="cwebmacronumber">9.2</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="reserved">c_structure</span><span class="plain"> *</span><span class="identifier">str</span><span class="plain">;</span>
|
|
<span class="identifier">LOOP_OVER_LINKED_LIST</span><span class="plain">(</span><span class="identifier">str</span><span class="plain">, </span><span class="reserved">c_structure</span><span class="plain">, </span><span class="identifier">W</span><span class="plain">-</span><span class="element">>c_structures</span><span class="plain">)</span>
|
|
<span class="identifier">str</span><span class="plain">-</span><span class="element">>tangled</span><span class="plain"> = </span><span class="constant">FALSE</span><span class="plain">;</span>
|
|
<span class="identifier">LOOP_OVER_LINKED_LIST</span><span class="plain">(</span><span class="identifier">str</span><span class="plain">, </span><span class="reserved">c_structure</span><span class="plain">, </span><span class="identifier">W</span><span class="plain">-</span><span class="element">>c_structures</span><span class="plain">)</span>
|
|
<span class="functiontext">CLike::tangle_structure</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">self</span><span class="plain">, </span><span class="identifier">str</span><span class="plain">);</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP9">§9</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP9_3"></a><b>§9.3. </b>Using the following recursion, which is therefore terminating:
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">CLike::tangle_structure</span><span class="plain">(</span><span class="constant">OUTPUT_STREAM</span><span class="plain">, </span><span class="reserved">programming_language</span><span class="plain"> *</span><span class="identifier">self</span><span class="plain">, </span><span class="reserved">c_structure</span><span class="plain"> *</span><span class="identifier">str</span><span class="plain">) {</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">str</span><span class="plain">-</span><span class="element">>tangled</span><span class="plain"> != </span><span class="constant">FALSE</span><span class="plain">) </span><span class="reserved">return</span><span class="plain">;</span>
|
|
<span class="identifier">str</span><span class="plain">-</span><span class="element">>tangled</span><span class="plain"> = </span><span class="constant">NOT_APPLICABLE</span><span class="plain">;</span>
|
|
<span class="reserved">c_structure</span><span class="plain"> *</span><span class="identifier">embodied</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
|
|
<span class="identifier">LOOP_OVER_LINKED_LIST</span><span class="plain">(</span><span class="identifier">embodied</span><span class="plain">, </span><span class="reserved">c_structure</span><span class="plain">, </span><span class="identifier">str</span><span class="plain">-</span><span class="element">>incorporates</span><span class="plain">)</span>
|
|
<span class="functiontext">CLike::tangle_structure</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">self</span><span class="plain">, </span><span class="identifier">embodied</span><span class="plain">);</span>
|
|
<span class="identifier">str</span><span class="plain">-</span><span class="element">>tangled</span><span class="plain"> = </span><span class="constant">TRUE</span><span class="plain">;</span>
|
|
<span class="functiontext">Tags::open_ifdefs</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">str</span><span class="plain">-</span><span class="element">>typedef_begins</span><span class="plain">-</span><span class="element">>owning_paragraph</span><span class="plain">);</span>
|
|
<span class="functiontext">Languages::insert_line_marker</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">self</span><span class="plain">, </span><span class="identifier">str</span><span class="plain">-</span><span class="element">>typedef_begins</span><span class="plain">);</span>
|
|
<span class="reserved">for</span><span class="plain"> (</span><span class="reserved">source_line</span><span class="plain"> *</span><span class="identifier">L</span><span class="plain"> = </span><span class="identifier">str</span><span class="plain">-</span><span class="element">>typedef_begins</span><span class="plain">; </span><span class="identifier">L</span><span class="plain">; </span><span class="identifier">L</span><span class="plain"> = </span><span class="identifier">L</span><span class="plain">-</span><span class="element">>next_line</span><span class="plain">) {</span>
|
|
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"%S\</span><span class="plain">n</span><span class="string">"</span><span class="plain">, </span><span class="identifier">L</span><span class="plain">-</span><span class="element">>text</span><span class="plain">);</span>
|
|
<span class="identifier">L</span><span class="plain">-</span><span class="element">>suppress_tangling</span><span class="plain"> = </span><span class="constant">TRUE</span><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">L</span><span class="plain"> == </span><span class="identifier">str</span><span class="plain">-</span><span class="element">>typedef_ends</span><span class="plain">) </span><span class="reserved">break</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
<span class="functiontext">Tags::close_ifdefs</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">str</span><span class="plain">-</span><span class="element">>typedef_begins</span><span class="plain">-</span><span class="element">>owning_paragraph</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function CLike::tangle_structure is used in <a href="#SP9_2">§9.2</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP9_4"></a><b>§9.4. </b>Functions are rather easier to deal with. In general, if a function was
|
|
defined within some number of nested <code class="display"><span class="extract">#ifdef</span></code> or <code class="display"><span class="extract">#ifndef</span></code> directives, then
|
|
we reproduce those around the predeclaration: except, as a special trick,
|
|
if the line contains a particular comment. For example:
|
|
</p>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="plain">#ifdef SOLARIS /* inweb: always predeclare */</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph">That exempts any functions inside this condition from meeting the condition
|
|
in order to be predeclared. It's a trick used in the foundation module just
|
|
a couple of times: the idea is that although a definition of the functions
|
|
is given which only works under SOLARIS, an external piece of code will
|
|
provide alternative function definitions which would work without SOLARIS.
|
|
The functions therefore need predeclaration regardless, because they will
|
|
exist either way.
|
|
</p>
|
|
|
|
|
|
<p class="macrodefinition"><code class="display">
|
|
<<span class="cwebmacrodefn">Predeclare the functions</span> <span class="cwebmacronumber">9.4</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="reserved">chapter</span><span class="plain"> *</span><span class="identifier">C</span><span class="plain">;</span>
|
|
<span class="reserved">section</span><span class="plain"> *</span><span class="identifier">S</span><span class="plain">;</span>
|
|
<span class="identifier">LOOP_WITHIN_TANGLE</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">, </span><span class="identifier">S</span><span class="plain">, </span><span class="functiontext">Tangler::primary_target</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">))</span>
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">L</span><span class="plain">-</span><span class="element">>function_defined</span><span class="plain">) && (</span><span class="identifier">L</span><span class="plain">-</span><span class="element">>owning_paragraph</span><span class="plain">-</span><span class="element">>placed_very_early</span><span class="plain"> == </span><span class="constant">FALSE</span><span class="plain">)) {</span>
|
|
<span class="reserved">function</span><span class="plain"> *</span><span class="identifier">fn</span><span class="plain"> = </span><span class="identifier">L</span><span class="plain">-</span><span class="element">>function_defined</span><span class="plain">;</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">to_close</span><span class="plain"> = 0;</span>
|
|
<span class="reserved">for</span><span class="plain"> (</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">i</span><span class="plain">=0; </span><span class="identifier">i</span><span class="plain"><</span><span class="identifier">fn</span><span class="plain">-</span><span class="element">>no_conditionals</span><span class="plain">; </span><span class="identifier">i</span><span class="plain">++) {</span>
|
|
<span class="reserved">match_results</span><span class="plain"> </span><span class="identifier">mr</span><span class="plain"> = </span><span class="functiontext">Regexp::create_mr</span><span class="plain">();</span>
|
|
<span class="reserved">if</span><span class="plain"> (!(</span><span class="functiontext">Regexp::match</span><span class="plain">(&</span><span class="identifier">mr</span><span class="plain">, </span><span class="identifier">fn</span><span class="plain">-</span><span class="element">>within_conditionals</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">]-</span><span class="element">>text</span><span class="plain">,</span>
|
|
<span class="identifier">L</span><span class="string">"%c*inweb: always predeclare%c*"</span><span class="plain">))) {</span>
|
|
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"%S\</span><span class="plain">n</span><span class="string">"</span><span class="plain">, </span><span class="identifier">fn</span><span class="plain">-</span><span class="element">>within_conditionals</span><span class="plain">[</span><span class="identifier">i</span><span class="plain">]-</span><span class="element">>text</span><span class="plain">);</span>
|
|
<span class="identifier">to_close</span><span class="plain">++;</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">}</span>
|
|
<span class="functiontext">Tags::open_ifdefs</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">L</span><span class="plain">-</span><span class="element">>owning_paragraph</span><span class="plain">);</span>
|
|
<span class="functiontext">Languages::insert_line_marker</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">W</span><span class="plain">-</span><span class="element">>main_language</span><span class="plain">, </span><span class="identifier">L</span><span class="plain">);</span>
|
|
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"%S "</span><span class="plain">, </span><span class="identifier">fn</span><span class="plain">-</span><span class="element">>function_type</span><span class="plain">);</span>
|
|
<span class="functiontext">Languages::tangle_code</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">W</span><span class="plain">-</span><span class="element">>main_language</span><span class="plain">, </span><span class="identifier">fn</span><span class="plain">-</span><span class="element">>function_name</span><span class="plain">);</span>
|
|
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"(%S;\</span><span class="plain">n</span><span class="string">"</span><span class="plain">, </span><span class="identifier">fn</span><span class="plain">-</span><span class="element">>function_arguments</span><span class="plain">);</span>
|
|
<span class="functiontext">Tags::close_ifdefs</span><span class="plain">(</span><span class="identifier">OUT</span><span class="plain">, </span><span class="identifier">L</span><span class="plain">-</span><span class="element">>owning_paragraph</span><span class="plain">);</span>
|
|
<span class="reserved">for</span><span class="plain"> (</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">i</span><span class="plain">=0; </span><span class="identifier">i</span><span class="plain"><</span><span class="identifier">to_close</span><span class="plain">; </span><span class="identifier">i</span><span class="plain">++) {</span>
|
|
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"#endif\</span><span class="plain">n</span><span class="string">"</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP9">§9</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP10"></a><b>§10. Line markers. </b>In order for C compilers to report C syntax errors on the correct line,
|
|
despite rearranging by automatic tools, C conventionally recognises the
|
|
preprocessor directive <code class="display"><span class="extract">#line</span></code> to tell it that a contiguous extract follows
|
|
from the given file; we generate this automatically.
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">CLike::insert_line_marker</span><span class="plain">(</span><span class="reserved">programming_language</span><span class="plain"> *</span><span class="identifier">self</span><span class="plain">, </span><span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">OUT</span><span class="plain">, </span><span class="reserved">source_line</span><span class="plain"> *</span><span class="identifier">L</span><span class="plain">) {</span>
|
|
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"#line %d \</span><span class="plain">"</span><span class="string">%/f\</span><span class="plain">"</span><span class="string">\</span><span class="plain">n</span><span class="string">"</span><span class="plain">,</span>
|
|
<span class="identifier">L</span><span class="plain">-</span><span class="element">>source.line_count</span><span class="plain">,</span>
|
|
<span class="identifier">L</span><span class="plain">-</span><span class="element">>source.text_file_filename</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function CLike::insert_line_marker is used in <a href="#SP2">§2</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP11"></a><b>§11. Comments. </b>We write comments the old-fashioned way, that is, not using <code class="display"><span class="extract">//</span></code>.
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">CLike::comment</span><span class="plain">(</span><span class="reserved">programming_language</span><span class="plain"> *</span><span class="identifier">self</span><span class="plain">, </span><span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">OUT</span><span class="plain">, </span><span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">comm</span><span class="plain">) {</span>
|
|
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"/* %S */\</span><span class="plain">n</span><span class="string">"</span><span class="plain">, </span><span class="identifier">comm</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function CLike::comment is used in <a href="#SP2">§2</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP12"></a><b>§12. </b>When parsing, we do recognise <code class="display"><span class="extract">//</span></code> comments, but we have to be careful not to
|
|
react to comment markers inside comments or double-qupted text which is outside
|
|
of comments, all of which makes this a little elaborate:
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">CLike::parse_comment</span><span class="plain">(</span><span class="reserved">programming_language</span><span class="plain"> *</span><span class="identifier">self</span><span class="plain">,</span>
|
|
<span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">line</span><span class="plain">, </span><span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">part_before_comment</span><span class="plain">, </span><span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">part_within_comment</span><span class="plain">) {</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">q_mode</span><span class="plain"> = </span><span class="constant">FALSE</span><span class="plain">, </span><span class="identifier">c_mode</span><span class="plain"> = </span><span class="constant">FALSE</span><span class="plain">, </span><span class="identifier">non_white_space</span><span class="plain"> = </span><span class="constant">FALSE</span><span class="plain">, </span><span class="identifier">c_position</span><span class="plain"> = -1, </span><span class="identifier">c_end</span><span class="plain"> = -1;</span>
|
|
<span class="reserved">for</span><span class="plain"> (</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">i</span><span class="plain">=0; </span><span class="identifier">i</span><span class="plain"><</span><span class="functiontext">Str::len</span><span class="plain">(</span><span class="identifier">line</span><span class="plain">); </span><span class="identifier">i</span><span class="plain">++) {</span>
|
|
<span class="identifier">wchar_t</span><span class="plain"> </span><span class="identifier">c</span><span class="plain"> = </span><span class="functiontext">Str::get_at</span><span class="plain">(</span><span class="identifier">line</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">c_mode</span><span class="plain">) {</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">c</span><span class="plain"> == </span><span class="character">'*'</span><span class="plain">) {</span>
|
|
<span class="identifier">wchar_t</span><span class="plain"> </span><span class="identifier">d</span><span class="plain"> = </span><span class="functiontext">Str::get_at</span><span class="plain">(</span><span class="identifier">line</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">+1);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">d</span><span class="plain"> == </span><span class="character">'/'</span><span class="plain">) { </span><span class="identifier">c_mode</span><span class="plain"> = </span><span class="constant">FALSE</span><span class="plain">; </span><span class="identifier">c_end</span><span class="plain"> = </span><span class="identifier">i</span><span class="plain">; </span><span class="identifier">i</span><span class="plain">++; }</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
|
|
<span class="reserved">if</span><span class="plain"> (!(</span><span class="functiontext">Characters::is_whitespace</span><span class="plain">(</span><span class="identifier">c</span><span class="plain">))) </span><span class="identifier">non_white_space</span><span class="plain"> = </span><span class="constant">TRUE</span><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">c</span><span class="plain"> == </span><span class="character">'\</span><span class="plain">\</span><span class="character">'</span><span class="plain">) && (</span><span class="identifier">q_mode</span><span class="plain">)) </span><span class="identifier">i</span><span class="plain"> += 1;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">c</span><span class="plain"> == </span><span class="character">'"'</span><span class="plain">) </span><span class="identifier">q_mode</span><span class="plain"> = </span><span class="identifier">q_mode</span><span class="plain">?</span><span class="constant">FALSE</span><span class="plain">:</span><span class="constant">TRUE</span><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">c</span><span class="plain"> == </span><span class="character">'/'</span><span class="plain">) && (!</span><span class="identifier">q_mode</span><span class="plain">)) {</span>
|
|
<span class="identifier">wchar_t</span><span class="plain"> </span><span class="identifier">d</span><span class="plain"> = </span><span class="functiontext">Str::get_at</span><span class="plain">(</span><span class="identifier">line</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">+1);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">d</span><span class="plain"> == </span><span class="character">'/'</span><span class="plain">) { </span><span class="identifier">c_mode</span><span class="plain"> = </span><span class="constant">TRUE</span><span class="plain">; </span><span class="identifier">c_position</span><span class="plain"> = </span><span class="identifier">i</span><span class="plain">; </span><span class="identifier">c_end</span><span class="plain"> = </span><span class="functiontext">Str::len</span><span class="plain">(</span><span class="identifier">line</span><span class="plain">); </span><span class="identifier">non_white_space</span><span class="plain"> = </span><span class="constant">FALSE</span><span class="plain">; </span><span class="reserved">break</span><span class="plain">; }</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">d</span><span class="plain"> == </span><span class="character">'*'</span><span class="plain">) { </span><span class="identifier">c_mode</span><span class="plain"> = </span><span class="constant">TRUE</span><span class="plain">; </span><span class="identifier">c_position</span><span class="plain"> = </span><span class="identifier">i</span><span class="plain">; </span><span class="identifier">non_white_space</span><span class="plain"> = </span><span class="constant">FALSE</span><span class="plain">; }</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">}</span>
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">c_position</span><span class="plain"> >= 0) && (</span><span class="identifier">non_white_space</span><span class="plain"> == </span><span class="constant">FALSE</span><span class="plain">)) {</span>
|
|
<span class="functiontext">Str::clear</span><span class="plain">(</span><span class="identifier">part_before_comment</span><span class="plain">);</span>
|
|
<span class="reserved">for</span><span class="plain"> (</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">i</span><span class="plain">=0; </span><span class="identifier">i</span><span class="plain"><</span><span class="identifier">c_position</span><span class="plain">; </span><span class="identifier">i</span><span class="plain">++) </span><span class="identifier">PUT_TO</span><span class="plain">(</span><span class="identifier">part_before_comment</span><span class="plain">, </span><span class="functiontext">Str::get_at</span><span class="plain">(</span><span class="identifier">line</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">));</span>
|
|
<span class="functiontext">Str::clear</span><span class="plain">(</span><span class="identifier">part_within_comment</span><span class="plain">);</span>
|
|
<span class="reserved">for</span><span class="plain"> (</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">i</span><span class="plain">=</span><span class="identifier">c_position</span><span class="plain"> + 2; </span><span class="identifier">i</span><span class="plain"><</span><span class="identifier">c_end</span><span class="plain">; </span><span class="identifier">i</span><span class="plain">++) </span><span class="identifier">PUT_TO</span><span class="plain">(</span><span class="identifier">part_within_comment</span><span class="plain">, </span><span class="functiontext">Str::get_at</span><span class="plain">(</span><span class="identifier">line</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">));</span>
|
|
<span class="functiontext">Str::trim_white_space</span><span class="plain">(</span><span class="identifier">part_within_comment</span><span class="plain">);</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="constant">TRUE</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="constant">FALSE</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function CLike::parse_comment is used in <a href="#SP2">§2</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP13"></a><b>§13. Ifdefs. </b></p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">CLike::open_ifdef</span><span class="plain">(</span><span class="reserved">programming_language</span><span class="plain"> *</span><span class="identifier">self</span><span class="plain">, </span><span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">OUT</span><span class="plain">, </span><span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">symbol</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">sense</span><span class="plain">) {</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">sense</span><span class="plain">) </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"#ifdef %S\</span><span class="plain">n</span><span class="string">"</span><span class="plain">, </span><span class="identifier">symbol</span><span class="plain">);</span>
|
|
<span class="reserved">else</span><span class="plain"> </span><span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"#ifndef %S\</span><span class="plain">n</span><span class="string">"</span><span class="plain">, </span><span class="identifier">symbol</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">CLike::close_ifdef</span><span class="plain">(</span><span class="reserved">programming_language</span><span class="plain"> *</span><span class="identifier">self</span><span class="plain">, </span><span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">OUT</span><span class="plain">, </span><span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">symbol</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">sense</span><span class="plain">) {</span>
|
|
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"#endif /* %S */\</span><span class="plain">n</span><span class="string">"</span><span class="plain">, </span><span class="identifier">symbol</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function CLike::open_ifdef is used in <a href="#SP2">§2</a>.</p>
|
|
|
|
<p class="endnote">The function CLike::close_ifdef is used in <a href="#SP2">§2</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP14"></a><b>§14. Before and after expansion. </b>Places braces before and after expanded paragraph macros ensures that code like
|
|
</p>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="plain">if (x == y) @<Do something dramatic@>;</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph">tangles to something like this:
|
|
</p>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="plain">if (x == y)</span>
|
|
<span class="plain">{</span>
|
|
<span class="plain">...</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph">so that the variables defined inside the macro have limited scope, and so that
|
|
multi-line macros are treated as a single statement by <code class="display"><span class="extract">if</span></code>, <code class="display"><span class="extract">while</span></code> and so on.
|
|
(The new-line before the opening brace protects us against problems with
|
|
Perl comments; Perl shares this code.)
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">CLike::before_macro_expansion</span><span class="plain">(</span><span class="reserved">programming_language</span><span class="plain"> *</span><span class="identifier">self</span><span class="plain">, </span><span class="constant">OUTPUT_STREAM</span><span class="plain">, </span><span class="reserved">para_macro</span><span class="plain"> *</span><span class="identifier">pmac</span><span class="plain">) {</span>
|
|
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"\</span><span class="plain">n</span><span class="string">{\</span><span class="plain">n</span><span class="string">"</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">CLike::after_macro_expansion</span><span class="plain">(</span><span class="reserved">programming_language</span><span class="plain"> *</span><span class="identifier">self</span><span class="plain">, </span><span class="constant">OUTPUT_STREAM</span><span class="plain">, </span><span class="reserved">para_macro</span><span class="plain"> *</span><span class="identifier">pmac</span><span class="plain">) {</span>
|
|
<span class="identifier">WRITE</span><span class="plain">(</span><span class="string">"}\</span><span class="plain">n</span><span class="string">"</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function CLike::before_macro_expansion is used in <a href="#SP2">§2</a>.</p>
|
|
|
|
<p class="endnote">The function CLike::after_macro_expansion is used in <a href="#SP2">§2</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP15"></a><b>§15. Begin weave. </b>We use this opportunity only to register C's usual set of reserved words as
|
|
being of interest for syntax colouring. <code class="display"><span class="extract">FILE</span></code> gets in even though it's not
|
|
technically reserved but only a type name, defined in the standard C library.
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">CLike::begin_weave</span><span class="plain">(</span><span class="reserved">programming_language</span><span class="plain"> *</span><span class="identifier">self</span><span class="plain">, </span><span class="reserved">section</span><span class="plain"> *</span><span class="identifier">S</span><span class="plain">, </span><span class="reserved">weave_target</span><span class="plain"> *</span><span class="identifier">wv</span><span class="plain">) {</span>
|
|
<span class="functiontext">Analyser::mark_reserved_word</span><span class="plain">(</span><span class="identifier">S</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"FILE"</span><span class="plain">, </span><span class="constant">RESERVED_COLOUR</span><span class="plain">);</span>
|
|
|
|
<span class="functiontext">Analyser::mark_reserved_word</span><span class="plain">(</span><span class="identifier">S</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"auto"</span><span class="plain">, </span><span class="constant">RESERVED_COLOUR</span><span class="plain">);</span>
|
|
<span class="functiontext">Analyser::mark_reserved_word</span><span class="plain">(</span><span class="identifier">S</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"break"</span><span class="plain">, </span><span class="constant">RESERVED_COLOUR</span><span class="plain">);</span>
|
|
<span class="functiontext">Analyser::mark_reserved_word</span><span class="plain">(</span><span class="identifier">S</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"case"</span><span class="plain">, </span><span class="constant">RESERVED_COLOUR</span><span class="plain">);</span>
|
|
<span class="functiontext">Analyser::mark_reserved_word</span><span class="plain">(</span><span class="identifier">S</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"char"</span><span class="plain">, </span><span class="constant">RESERVED_COLOUR</span><span class="plain">);</span>
|
|
<span class="functiontext">Analyser::mark_reserved_word</span><span class="plain">(</span><span class="identifier">S</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"const"</span><span class="plain">, </span><span class="constant">RESERVED_COLOUR</span><span class="plain">);</span>
|
|
<span class="functiontext">Analyser::mark_reserved_word</span><span class="plain">(</span><span class="identifier">S</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"continue"</span><span class="plain">, </span><span class="constant">RESERVED_COLOUR</span><span class="plain">);</span>
|
|
<span class="functiontext">Analyser::mark_reserved_word</span><span class="plain">(</span><span class="identifier">S</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"default"</span><span class="plain">, </span><span class="constant">RESERVED_COLOUR</span><span class="plain">);</span>
|
|
<span class="functiontext">Analyser::mark_reserved_word</span><span class="plain">(</span><span class="identifier">S</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"do"</span><span class="plain">, </span><span class="constant">RESERVED_COLOUR</span><span class="plain">);</span>
|
|
<span class="functiontext">Analyser::mark_reserved_word</span><span class="plain">(</span><span class="identifier">S</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"double"</span><span class="plain">, </span><span class="constant">RESERVED_COLOUR</span><span class="plain">);</span>
|
|
<span class="functiontext">Analyser::mark_reserved_word</span><span class="plain">(</span><span class="identifier">S</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"else"</span><span class="plain">, </span><span class="constant">RESERVED_COLOUR</span><span class="plain">);</span>
|
|
<span class="functiontext">Analyser::mark_reserved_word</span><span class="plain">(</span><span class="identifier">S</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"enum"</span><span class="plain">, </span><span class="constant">RESERVED_COLOUR</span><span class="plain">);</span>
|
|
<span class="functiontext">Analyser::mark_reserved_word</span><span class="plain">(</span><span class="identifier">S</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"extern"</span><span class="plain">, </span><span class="constant">RESERVED_COLOUR</span><span class="plain">);</span>
|
|
<span class="functiontext">Analyser::mark_reserved_word</span><span class="plain">(</span><span class="identifier">S</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"float"</span><span class="plain">, </span><span class="constant">RESERVED_COLOUR</span><span class="plain">);</span>
|
|
<span class="functiontext">Analyser::mark_reserved_word</span><span class="plain">(</span><span class="identifier">S</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"for"</span><span class="plain">, </span><span class="constant">RESERVED_COLOUR</span><span class="plain">);</span>
|
|
<span class="functiontext">Analyser::mark_reserved_word</span><span class="plain">(</span><span class="identifier">S</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"goto"</span><span class="plain">, </span><span class="constant">RESERVED_COLOUR</span><span class="plain">);</span>
|
|
<span class="functiontext">Analyser::mark_reserved_word</span><span class="plain">(</span><span class="identifier">S</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"if"</span><span class="plain">, </span><span class="constant">RESERVED_COLOUR</span><span class="plain">);</span>
|
|
<span class="functiontext">Analyser::mark_reserved_word</span><span class="plain">(</span><span class="identifier">S</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"int"</span><span class="plain">, </span><span class="constant">RESERVED_COLOUR</span><span class="plain">);</span>
|
|
<span class="functiontext">Analyser::mark_reserved_word</span><span class="plain">(</span><span class="identifier">S</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"long"</span><span class="plain">, </span><span class="constant">RESERVED_COLOUR</span><span class="plain">);</span>
|
|
<span class="functiontext">Analyser::mark_reserved_word</span><span class="plain">(</span><span class="identifier">S</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"register"</span><span class="plain">, </span><span class="constant">RESERVED_COLOUR</span><span class="plain">);</span>
|
|
<span class="functiontext">Analyser::mark_reserved_word</span><span class="plain">(</span><span class="identifier">S</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"return"</span><span class="plain">, </span><span class="constant">RESERVED_COLOUR</span><span class="plain">);</span>
|
|
<span class="functiontext">Analyser::mark_reserved_word</span><span class="plain">(</span><span class="identifier">S</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"short"</span><span class="plain">, </span><span class="constant">RESERVED_COLOUR</span><span class="plain">);</span>
|
|
<span class="functiontext">Analyser::mark_reserved_word</span><span class="plain">(</span><span class="identifier">S</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"signed"</span><span class="plain">, </span><span class="constant">RESERVED_COLOUR</span><span class="plain">);</span>
|
|
<span class="functiontext">Analyser::mark_reserved_word</span><span class="plain">(</span><span class="identifier">S</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"sizeof"</span><span class="plain">, </span><span class="constant">RESERVED_COLOUR</span><span class="plain">);</span>
|
|
<span class="functiontext">Analyser::mark_reserved_word</span><span class="plain">(</span><span class="identifier">S</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"static"</span><span class="plain">, </span><span class="constant">RESERVED_COLOUR</span><span class="plain">);</span>
|
|
<span class="functiontext">Analyser::mark_reserved_word</span><span class="plain">(</span><span class="identifier">S</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"struct"</span><span class="plain">, </span><span class="constant">RESERVED_COLOUR</span><span class="plain">);</span>
|
|
<span class="functiontext">Analyser::mark_reserved_word</span><span class="plain">(</span><span class="identifier">S</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"switch"</span><span class="plain">, </span><span class="constant">RESERVED_COLOUR</span><span class="plain">);</span>
|
|
<span class="functiontext">Analyser::mark_reserved_word</span><span class="plain">(</span><span class="identifier">S</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"typedef"</span><span class="plain">, </span><span class="constant">RESERVED_COLOUR</span><span class="plain">);</span>
|
|
<span class="functiontext">Analyser::mark_reserved_word</span><span class="plain">(</span><span class="identifier">S</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"union"</span><span class="plain">, </span><span class="constant">RESERVED_COLOUR</span><span class="plain">);</span>
|
|
<span class="functiontext">Analyser::mark_reserved_word</span><span class="plain">(</span><span class="identifier">S</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"unsigned"</span><span class="plain">, </span><span class="constant">RESERVED_COLOUR</span><span class="plain">);</span>
|
|
<span class="functiontext">Analyser::mark_reserved_word</span><span class="plain">(</span><span class="identifier">S</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"void"</span><span class="plain">, </span><span class="constant">RESERVED_COLOUR</span><span class="plain">);</span>
|
|
<span class="functiontext">Analyser::mark_reserved_word</span><span class="plain">(</span><span class="identifier">S</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"volatile"</span><span class="plain">, </span><span class="constant">RESERVED_COLOUR</span><span class="plain">);</span>
|
|
<span class="functiontext">Analyser::mark_reserved_word</span><span class="plain">(</span><span class="identifier">S</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"while"</span><span class="plain">, </span><span class="constant">RESERVED_COLOUR</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function CLike::begin_weave is used in <a href="#SP2">§2</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP16"></a><b>§16. Syntax colouring. </b>This is a very simple syntax colouring algorithm. The state at any given
|
|
time is a single variable, the current category of code being looked at:
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">colouring_state</span><span class="plain"> = </span><span class="constant">PLAIN_COLOUR</span><span class="plain">;</span>
|
|
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">CLike::reset_syntax_colouring</span><span class="plain">(</span><span class="reserved">programming_language</span><span class="plain"> *</span><span class="identifier">self</span><span class="plain">) {</span>
|
|
<span class="identifier">colouring_state</span><span class="plain"> = </span><span class="constant">PLAIN_COLOUR</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function CLike::reset_syntax_colouring is used in <a href="#SP2">§2</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP17"></a><b>§17. </b></p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="functiontext">CLike::syntax_colour</span><span class="plain">(</span><span class="reserved">programming_language</span><span class="plain"> *</span><span class="identifier">self</span><span class="plain">, </span><span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">OUT</span><span class="plain">, </span><span class="reserved">weave_target</span><span class="plain"> *</span><span class="identifier">wv</span><span class="plain">,</span>
|
|
<span class="reserved">web</span><span class="plain"> *</span><span class="identifier">W</span><span class="plain">, </span><span class="reserved">chapter</span><span class="plain"> *</span><span class="identifier">C</span><span class="plain">, </span><span class="reserved">section</span><span class="plain"> *</span><span class="identifier">S</span><span class="plain">, </span><span class="reserved">source_line</span><span class="plain"> *</span><span class="identifier">L</span><span class="plain">, </span><span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">matter</span><span class="plain">,</span>
|
|
<span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">colouring</span><span class="plain">) {</span>
|
|
<span class="reserved">for</span><span class="plain"> (</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">i</span><span class="plain">=0; </span><span class="identifier">i</span><span class="plain"> < </span><span class="functiontext">Str::len</span><span class="plain">(</span><span class="identifier">matter</span><span class="plain">); </span><span class="identifier">i</span><span class="plain">++) {</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">skip</span><span class="plain"> = </span><span class="constant">FALSE</span><span class="plain">, </span><span class="identifier">one_off</span><span class="plain"> = -1, </span><span class="identifier">will_be</span><span class="plain"> = -1;</span>
|
|
<span class="reserved">switch</span><span class="plain"> (</span><span class="identifier">colouring_state</span><span class="plain">) {</span>
|
|
<span class="reserved">case</span><span class="plain"> </span><span class="constant">PLAIN_COLOUR</span><span class="plain">:</span>
|
|
<span class="reserved">switch</span><span class="plain"> (</span><span class="functiontext">Str::get_at</span><span class="plain">(</span><span class="identifier">matter</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">)) {</span>
|
|
<span class="reserved">case</span><span class="plain"> </span><span class="character">'\</span><span class="plain">"</span><span class="character">'</span><span class="plain">: </span><span class="identifier">colouring_state</span><span class="plain"> = </span><span class="constant">STRING_COLOUR</span><span class="plain">; </span><span class="reserved">break</span><span class="plain">;</span>
|
|
<span class="reserved">case</span><span class="plain"> </span><span class="character">'\</span><span class="plain">'</span><span class="character">'</span><span class="plain">: </span><span class="identifier">colouring_state</span><span class="plain"> = </span><span class="constant">CHAR_LITERAL_COLOUR</span><span class="plain">; </span><span class="reserved">break</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="functiontext">Regexp::identifier_char</span><span class="plain">(</span><span class="functiontext">Str::get_at</span><span class="plain">(</span><span class="identifier">matter</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">))) &&</span>
|
|
<span class="plain">(</span><span class="functiontext">Str::get_at</span><span class="plain">(</span><span class="identifier">matter</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">) != </span><span class="character">':'</span><span class="plain">)) {</span>
|
|
<span class="reserved">if</span><span class="plain"> ((!(</span><span class="identifier">isdigit</span><span class="plain">(</span><span class="functiontext">Str::get_at</span><span class="plain">(</span><span class="identifier">matter</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">)))) ||</span>
|
|
<span class="plain">((</span><span class="identifier">i</span><span class="plain">>0) && (</span><span class="functiontext">Str::get_at</span><span class="plain">(</span><span class="identifier">colouring</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">-1) == </span><span class="constant">IDENTIFIER_COLOUR</span><span class="plain">)))</span>
|
|
<span class="identifier">one_off</span><span class="plain"> = </span><span class="constant">IDENTIFIER_COLOUR</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
<span class="reserved">break</span><span class="plain">;</span>
|
|
<span class="reserved">case</span><span class="plain"> </span><span class="constant">CHAR_LITERAL_COLOUR</span><span class="plain">:</span>
|
|
<span class="reserved">switch</span><span class="plain"> (</span><span class="functiontext">Str::get_at</span><span class="plain">(</span><span class="identifier">matter</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">)) {</span>
|
|
<span class="reserved">case</span><span class="plain"> </span><span class="character">'\</span><span class="plain">\</span><span class="character">'</span><span class="plain">: </span><span class="identifier">skip</span><span class="plain"> = </span><span class="constant">TRUE</span><span class="plain">; </span><span class="reserved">break</span><span class="plain">;</span>
|
|
<span class="reserved">case</span><span class="plain"> </span><span class="character">'\</span><span class="plain">'</span><span class="character">'</span><span class="plain">: </span><span class="identifier">will_be</span><span class="plain"> = </span><span class="constant">PLAIN_COLOUR</span><span class="plain">; </span><span class="reserved">break</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
<span class="reserved">break</span><span class="plain">;</span>
|
|
<span class="reserved">case</span><span class="plain"> </span><span class="constant">STRING_COLOUR</span><span class="plain">:</span>
|
|
<span class="reserved">switch</span><span class="plain"> (</span><span class="functiontext">Str::get_at</span><span class="plain">(</span><span class="identifier">matter</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">)) {</span>
|
|
<span class="reserved">case</span><span class="plain"> </span><span class="character">'\</span><span class="plain">\</span><span class="character">'</span><span class="plain">: </span><span class="identifier">skip</span><span class="plain"> = </span><span class="constant">TRUE</span><span class="plain">; </span><span class="reserved">break</span><span class="plain">;</span>
|
|
<span class="reserved">case</span><span class="plain"> </span><span class="character">'\</span><span class="plain">"</span><span class="character">'</span><span class="plain">: </span><span class="identifier">will_be</span><span class="plain"> = </span><span class="constant">PLAIN_COLOUR</span><span class="plain">; </span><span class="reserved">break</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
<span class="reserved">break</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">one_off</span><span class="plain"> >= 0) </span><span class="functiontext">Str::put_at</span><span class="plain">(</span><span class="identifier">colouring</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">, (</span><span class="reserved">char</span><span class="plain">) </span><span class="identifier">one_off</span><span class="plain">);</span>
|
|
<span class="reserved">else</span><span class="plain"> </span><span class="functiontext">Str::put_at</span><span class="plain">(</span><span class="identifier">colouring</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">, (</span><span class="reserved">char</span><span class="plain">) </span><span class="identifier">colouring_state</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">will_be</span><span class="plain"> >= 0) </span><span class="identifier">colouring_state</span><span class="plain"> = (</span><span class="reserved">char</span><span class="plain">) </span><span class="identifier">will_be</span><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">skip</span><span class="plain">) && (</span><span class="functiontext">Str::get_at</span><span class="plain">(</span><span class="identifier">matter</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">+1))) </span><span class="identifier">i</span><span class="plain">++;</span>
|
|
<span class="plain">}</span>
|
|
<<span class="cwebmacro">Find identifiers and colour them appropriately</span> <span class="cwebmacronumber">17.1</span>><span class="plain">;</span>
|
|
<span class="reserved">return</span><span class="plain"> </span><span class="constant">FALSE</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function CLike::syntax_colour is used in <a href="#SP2">§2</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP17_1"></a><b>§17.1. </b>Note that an identifier, followed by <code class="display"><span class="extract">::</span></code> and then another identifier, is
|
|
merged here into one long identifier. Thus in the code <code class="display"><span class="extract">r = X::Y(1);</span></code>, the
|
|
above routine would identify three identifiers, <code class="display"><span class="extract">r</span></code>, <code class="display"><span class="extract">X</span></code> and <code class="display"><span class="extract">Y</span></code>; but the
|
|
code below merges these into <code class="display"><span class="extract">r</span></code> and <code class="display"><span class="extract">X::Y</span></code>.
|
|
</p>
|
|
|
|
|
|
<p class="macrodefinition"><code class="display">
|
|
<<span class="cwebmacrodefn">Find identifiers and colour them appropriately</span> <span class="cwebmacronumber">17.1</span>> =
|
|
</code></p>
|
|
|
|
|
|
<pre class="displaydefn">
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">ident_from</span><span class="plain"> = -1;</span>
|
|
<span class="reserved">for</span><span class="plain"> (</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">i</span><span class="plain">=0; </span><span class="identifier">i</span><span class="plain"> < </span><span class="functiontext">Str::len</span><span class="plain">(</span><span class="identifier">matter</span><span class="plain">); </span><span class="identifier">i</span><span class="plain">++) {</span>
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="functiontext">Str::get_at</span><span class="plain">(</span><span class="identifier">matter</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">) == </span><span class="character">':'</span><span class="plain">) && (</span><span class="functiontext">Str::get_at</span><span class="plain">(</span><span class="identifier">matter</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">+1) == </span><span class="character">':'</span><span class="plain">) &&</span>
|
|
<span class="plain">(</span><span class="functiontext">Str::get_at</span><span class="plain">(</span><span class="identifier">colouring</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">-1) == </span><span class="constant">IDENTIFIER_COLOUR</span><span class="plain">) &&</span>
|
|
<span class="plain">(</span><span class="functiontext">Str::get_at</span><span class="plain">(</span><span class="identifier">colouring</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">+2) == </span><span class="constant">IDENTIFIER_COLOUR</span><span class="plain">)) {</span>
|
|
<span class="functiontext">Str::put_at</span><span class="plain">(</span><span class="identifier">colouring</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">, </span><span class="constant">IDENTIFIER_COLOUR</span><span class="plain">);</span>
|
|
<span class="functiontext">Str::put_at</span><span class="plain">(</span><span class="identifier">colouring</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">+1, </span><span class="constant">IDENTIFIER_COLOUR</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Str::get_at</span><span class="plain">(</span><span class="identifier">colouring</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">) == </span><span class="constant">IDENTIFIER_COLOUR</span><span class="plain">) {</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ident_from</span><span class="plain"> == -1) </span><span class="identifier">ident_from</span><span class="plain"> = </span><span class="identifier">i</span><span class="plain">;</span>
|
|
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ident_from</span><span class="plain"> >= 0)</span>
|
|
<span class="functiontext">CLike::colour_ident</span><span class="plain">(</span><span class="identifier">S</span><span class="plain">, </span><span class="identifier">matter</span><span class="plain">, </span><span class="identifier">colouring</span><span class="plain">, </span><span class="identifier">ident_from</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">-1);</span>
|
|
<span class="identifier">ident_from</span><span class="plain"> = -1;</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">}</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">ident_from</span><span class="plain"> >= 0)</span>
|
|
<span class="functiontext">CLike::colour_ident</span><span class="plain">(</span><span class="identifier">S</span><span class="plain">, </span><span class="identifier">matter</span><span class="plain">, </span><span class="identifier">colouring</span><span class="plain">, </span><span class="identifier">ident_from</span><span class="plain">, </span><span class="functiontext">Str::len</span><span class="plain">(</span><span class="identifier">matter</span><span class="plain">)-1);</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">This code is used in <a href="#SP17">§17</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP18"></a><b>§18. </b>Here we look at a word made up of identifier characters — such as <code class="display"><span class="extract">int</span></code>, <code class="display"><span class="extract">X</span></code>,
|
|
or <code class="display"><span class="extract">CLike::colour_ident</span></code> — and decide whether to recolour its characters on
|
|
the basis of what it means.
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">CLike::colour_ident</span><span class="plain">(</span><span class="reserved">section</span><span class="plain"> *</span><span class="identifier">S</span><span class="plain">, </span><span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">matter</span><span class="plain">, </span><span class="reserved">text_stream</span><span class="plain"> *</span><span class="identifier">colouring</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">from</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">to</span><span class="plain">) {</span>
|
|
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">id</span><span class="plain">);</span>
|
|
<span class="functiontext">Str::substr</span><span class="plain">(</span><span class="identifier">id</span><span class="plain">, </span><span class="functiontext">Str::at</span><span class="plain">(</span><span class="identifier">matter</span><span class="plain">, </span><span class="identifier">from</span><span class="plain">), </span><span class="functiontext">Str::at</span><span class="plain">(</span><span class="identifier">matter</span><span class="plain">, </span><span class="identifier">to</span><span class="plain">+1));</span>
|
|
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">override</span><span class="plain"> = -1;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Analyser::is_reserved_word</span><span class="plain">(</span><span class="identifier">S</span><span class="plain">, </span><span class="identifier">id</span><span class="plain">, </span><span class="constant">FUNCTION_COLOUR</span><span class="plain">)) </span><span class="identifier">override</span><span class="plain"> = </span><span class="constant">FUNCTION_COLOUR</span><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Analyser::is_reserved_word</span><span class="plain">(</span><span class="identifier">S</span><span class="plain">, </span><span class="identifier">id</span><span class="plain">, </span><span class="constant">RESERVED_COLOUR</span><span class="plain">)) </span><span class="identifier">override</span><span class="plain"> = </span><span class="constant">RESERVED_COLOUR</span><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Analyser::is_reserved_word</span><span class="plain">(</span><span class="identifier">S</span><span class="plain">, </span><span class="identifier">id</span><span class="plain">, </span><span class="constant">CONSTANT_COLOUR</span><span class="plain">)) </span><span class="identifier">override</span><span class="plain"> = </span><span class="constant">CONSTANT_COLOUR</span><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Analyser::is_reserved_word</span><span class="plain">(</span><span class="identifier">S</span><span class="plain">, </span><span class="identifier">id</span><span class="plain">, </span><span class="constant">ELEMENT_COLOUR</span><span class="plain">)) {</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">at</span><span class="plain"> = --</span><span class="identifier">from</span><span class="plain">;</span>
|
|
<span class="reserved">while</span><span class="plain"> ((</span><span class="identifier">at</span><span class="plain"> > 0) && (</span><span class="functiontext">Characters::is_space_or_tab</span><span class="plain">(</span><span class="functiontext">Str::get_at</span><span class="plain">(</span><span class="identifier">matter</span><span class="plain">, </span><span class="identifier">at</span><span class="plain">)))) </span><span class="identifier">at</span><span class="plain">--;</span>
|
|
<span class="reserved">if</span><span class="plain"> (((</span><span class="identifier">at</span><span class="plain"> >= 0) && (</span><span class="functiontext">Str::get_at</span><span class="plain">(</span><span class="identifier">matter</span><span class="plain">, </span><span class="identifier">at</span><span class="plain">) == </span><span class="character">'.'</span><span class="plain">)) ||</span>
|
|
<span class="plain">((</span><span class="identifier">at</span><span class="plain"> >= 0) && (</span><span class="functiontext">Str::get_at</span><span class="plain">(</span><span class="identifier">matter</span><span class="plain">, </span><span class="identifier">at</span><span class="plain">-1) == </span><span class="character">'-'</span><span class="plain">) && (</span><span class="functiontext">Str::get_at</span><span class="plain">(</span><span class="identifier">matter</span><span class="plain">, </span><span class="identifier">at</span><span class="plain">) == </span><span class="character">'>'</span><span class="plain">)))</span>
|
|
<span class="identifier">override</span><span class="plain"> = </span><span class="constant">ELEMENT_COLOUR</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">override</span><span class="plain"> >= 0)</span>
|
|
<span class="reserved">for</span><span class="plain"> (</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">i</span><span class="plain">=</span><span class="identifier">from</span><span class="plain">; </span><span class="identifier">i</span><span class="plain"><=</span><span class="identifier">to</span><span class="plain">; </span><span class="identifier">i</span><span class="plain">++)</span>
|
|
<span class="functiontext">Str::put_at</span><span class="plain">(</span><span class="identifier">colouring</span><span class="plain">, </span><span class="identifier">i</span><span class="plain">, </span><span class="identifier">override</span><span class="plain">);</span>
|
|
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">id</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function CLike::colour_ident is used in <a href="#SP17_1">§17.1</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP19"></a><b>§19. Overriding regular code weaving. </b>We have the opportunity here to sidestep the regular weaving algorithm, and do
|
|
our own thing. We decline.
|
|
</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP20"></a><b>§20. Analysis. </b>This implements the additional information in the <code class="display"><span class="extract">-structures</span></code> and <code class="display"><span class="extract">-functions</span></code>
|
|
fprms of section catalogue.
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">CLike::catalogue</span><span class="plain">(</span><span class="reserved">programming_language</span><span class="plain"> *</span><span class="identifier">self</span><span class="plain">, </span><span class="reserved">section</span><span class="plain"> *</span><span class="identifier">S</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">functions_too</span><span class="plain">) {</span>
|
|
<span class="reserved">c_structure</span><span class="plain"> *</span><span class="identifier">str</span><span class="plain">;</span>
|
|
<span class="identifier">LOOP_OVER</span><span class="plain">(</span><span class="identifier">str</span><span class="plain">, </span><span class="reserved">c_structure</span><span class="plain">)</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">str</span><span class="plain">-</span><span class="element">>typedef_begins</span><span class="plain">-</span><span class="element">>owning_section</span><span class="plain"> == </span><span class="identifier">S</span><span class="plain">)</span>
|
|
<span class="identifier">PRINT</span><span class="plain">(</span><span class="string">" %S "</span><span class="plain">, </span><span class="identifier">str</span><span class="plain">-</span><span class="element">>structure_name</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">functions_too</span><span class="plain">) {</span>
|
|
<span class="reserved">function</span><span class="plain"> *</span><span class="identifier">fn</span><span class="plain">;</span>
|
|
<span class="identifier">LOOP_OVER</span><span class="plain">(</span><span class="identifier">fn</span><span class="plain">, </span><span class="reserved">function</span><span class="plain">)</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">fn</span><span class="plain">-</span><span class="element">>function_header_at</span><span class="plain">-</span><span class="element">>owning_section</span><span class="plain"> == </span><span class="identifier">S</span><span class="plain">)</span>
|
|
<span class="identifier">PRINT</span><span class="plain">(</span><span class="string">"\</span><span class="plain">n</span><span class="string"> %S"</span><span class="plain">, </span><span class="identifier">fn</span><span class="plain">-</span><span class="element">>function_name</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function CLike::catalogue is used in <a href="#SP2">§2</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP21"></a><b>§21. </b>Having found all those functions and structure elements, we make sure they
|
|
are all known to Inweb's hash table of interesting identifiers:
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">CLike::analyse_code</span><span class="plain">(</span><span class="reserved">programming_language</span><span class="plain"> *</span><span class="identifier">self</span><span class="plain">, </span><span class="reserved">web</span><span class="plain"> *</span><span class="identifier">W</span><span class="plain">) {</span>
|
|
<span class="reserved">function</span><span class="plain"> *</span><span class="identifier">fn</span><span class="plain">;</span>
|
|
<span class="identifier">LOOP_OVER</span><span class="plain">(</span><span class="identifier">fn</span><span class="plain">, </span><span class="reserved">function</span><span class="plain">)</span>
|
|
<span class="functiontext">Analyser::find_hash_entry</span><span class="plain">(</span><span class="identifier">fn</span><span class="plain">-</span><span class="element">>function_header_at</span><span class="plain">-</span><span class="element">>owning_section</span><span class="plain">, </span><span class="identifier">fn</span><span class="plain">-</span><span class="element">>function_name</span><span class="plain">, </span><span class="constant">TRUE</span><span class="plain">);</span>
|
|
<span class="reserved">c_structure</span><span class="plain"> *</span><span class="identifier">str</span><span class="plain">;</span>
|
|
<span class="reserved">structure_element</span><span class="plain"> *</span><span class="identifier">elt</span><span class="plain">;</span>
|
|
<span class="identifier">LOOP_OVER_LINKED_LIST</span><span class="plain">(</span><span class="identifier">str</span><span class="plain">, </span><span class="reserved">c_structure</span><span class="plain">, </span><span class="identifier">W</span><span class="plain">-</span><span class="element">>c_structures</span><span class="plain">)</span>
|
|
<span class="identifier">LOOP_OVER_LINKED_LIST</span><span class="plain">(</span><span class="identifier">elt</span><span class="plain">, </span><span class="reserved">structure_element</span><span class="plain">, </span><span class="identifier">str</span><span class="plain">-</span><span class="element">>elements</span><span class="plain">)</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">elt</span><span class="plain">-</span><span class="element">>allow_sharing</span><span class="plain"> == </span><span class="constant">FALSE</span><span class="plain">)</span>
|
|
<span class="functiontext">Analyser::find_hash_entry</span><span class="plain">(</span><span class="identifier">elt</span><span class="plain">-</span><span class="element">>element_created_at</span><span class="plain">-</span><span class="element">>owning_section</span><span class="plain">,</span>
|
|
<span class="identifier">elt</span><span class="plain">-</span><span class="element">>element_name</span><span class="plain">, </span><span class="constant">TRUE</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function CLike::analyse_code is used in <a href="#SP2">§2</a>.</p>
|
|
|
|
<p class="inwebparagraph"><a id="SP22"></a><b>§22. </b>The following is an opportunity for us to scold the author for any
|
|
specifically C-like errors. We're going to look for functions named
|
|
<code class="display"><span class="extract">Whatever::name()</span></code> whose definitions are not in the <code class="display"><span class="extract">Whatever::</span></code> section;
|
|
in other words, we police the rule that functions actually are defined in the
|
|
namespace which their names imply. This can be turned off with a special
|
|
bibliographic variable, but don't do that.
|
|
</p>
|
|
|
|
|
|
<pre class="display">
|
|
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">CLike::post_analysis</span><span class="plain">(</span><span class="reserved">programming_language</span><span class="plain"> *</span><span class="identifier">self</span><span class="plain">, </span><span class="reserved">web</span><span class="plain"> *</span><span class="identifier">W</span><span class="plain">) {</span>
|
|
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">check_namespaces</span><span class="plain"> = </span><span class="constant">FALSE</span><span class="plain">;</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="functiontext">Str::eq_wide_string</span><span class="plain">(</span><span class="functiontext">Bibliographic::get_datum</span><span class="plain">(</span><span class="identifier">W</span><span class="plain">, </span><span class="identifier">I</span><span class="string">"Namespaces"</span><span class="plain">), </span><span class="identifier">L</span><span class="string">"On"</span><span class="plain">)) </span><span class="identifier">check_namespaces</span><span class="plain"> = </span><span class="constant">TRUE</span><span class="plain">;</span>
|
|
<span class="reserved">function</span><span class="plain"> *</span><span class="identifier">fn</span><span class="plain">;</span>
|
|
<span class="identifier">LOOP_OVER</span><span class="plain">(</span><span class="identifier">fn</span><span class="plain">, </span><span class="reserved">function</span><span class="plain">) {</span>
|
|
<span class="reserved">hash_table_entry</span><span class="plain"> *</span><span class="identifier">hte</span><span class="plain"> =</span>
|
|
<span class="functiontext">Analyser::find_hash_entry</span><span class="plain">(</span><span class="identifier">fn</span><span class="plain">-</span><span class="element">>function_header_at</span><span class="plain">-</span><span class="element">>owning_section</span><span class="plain">, </span><span class="identifier">fn</span><span class="plain">-</span><span class="element">>function_name</span><span class="plain">, </span><span class="constant">FALSE</span><span class="plain">);</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">hte</span><span class="plain">) {</span>
|
|
<span class="reserved">hash_table_entry_usage</span><span class="plain"> *</span><span class="identifier">hteu</span><span class="plain">;</span>
|
|
<span class="identifier">LOOP_OVER_LINKED_LIST</span><span class="plain">(</span><span class="identifier">hteu</span><span class="plain">, </span><span class="reserved">hash_table_entry_usage</span><span class="plain">, </span><span class="identifier">hte</span><span class="plain">-</span><span class="element">>usages</span><span class="plain">) {</span>
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">hteu</span><span class="plain">-</span><span class="element">>form_of_usage</span><span class="plain"> & </span><span class="constant">FCALL_USAGE</span><span class="plain">) || (</span><span class="identifier">fn</span><span class="plain">-</span><span class="element">>within_namespace</span><span class="plain">))</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">hteu</span><span class="plain">-</span><span class="element">>usage_recorded_at</span><span class="plain">-</span><span class="element">>under_section</span><span class="plain"> != </span><span class="identifier">fn</span><span class="plain">-</span><span class="element">>function_header_at</span><span class="plain">-</span><span class="element">>owning_section</span><span class="plain">)</span>
|
|
<span class="identifier">fn</span><span class="plain">-</span><span class="element">>called_from_other_sections</span><span class="plain"> = </span><span class="constant">TRUE</span><span class="plain">;</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">}</span>
|
|
<span class="reserved">if</span><span class="plain"> ((</span><span class="identifier">fn</span><span class="plain">-</span><span class="element">>within_namespace</span><span class="plain"> != </span><span class="identifier">fn</span><span class="plain">-</span><span class="element">>called_from_other_sections</span><span class="plain">)</span>
|
|
<span class="plain">&& (</span><span class="identifier">check_namespaces</span><span class="plain">)</span>
|
|
<span class="plain">&& (</span><span class="identifier">fn</span><span class="plain">-</span><span class="element">>call_freely</span><span class="plain"> == </span><span class="constant">FALSE</span><span class="plain">)) {</span>
|
|
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">fn</span><span class="plain">-</span><span class="element">>within_namespace</span><span class="plain">)</span>
|
|
<span class="functiontext">Main::error_in_web</span><span class="plain">(</span>
|
|
<span class="identifier">I</span><span class="string">"Being internally called, this function mustn't belong to a :: namespace"</span><span class="plain">,</span>
|
|
<span class="identifier">fn</span><span class="plain">-</span><span class="element">>function_header_at</span><span class="plain">);</span>
|
|
<span class="reserved">else</span>
|
|
<span class="functiontext">Main::error_in_web</span><span class="plain">(</span>
|
|
<span class="identifier">I</span><span class="string">"Being externally called, this function must belong to a :: namespace"</span><span class="plain">,</span>
|
|
<span class="identifier">fn</span><span class="plain">-</span><span class="element">>function_header_at</span><span class="plain">);</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">}</span>
|
|
<span class="plain">}</span>
|
|
</pre>
|
|
|
|
<p class="inwebparagraph"></p>
|
|
|
|
<p class="endnote">The function CLike::post_analysis is used in <a href="#SP2">§2</a>.</p>
|
|
|
|
<hr class="tocbar">
|
|
<ul class="toc"><li><a href="4-pl.html">Back to 'Programming Languages'</a></li><li><a href="4-is.html">Continue with 'InC Support'</a></li></ul><hr class="tocbar">
|
|
<!--End of weave-->
|
|
</body>
|
|
</html>
|
|
|