1
0
Fork 0
mirror of https://github.com/ganelson/inform.git synced 2024-07-18 06:54:26 +03:00
inform7/docs/inbuild-module/5-st.html
2020-02-27 11:18:25 +00:00

144 lines
16 KiB
HTML

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>4/pm</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 '5/st' generated by 7-->
<ul class="crumbs"><li><a href="../webs.html">&#9733;</a></li><li><a href="index.html">inbuild</a></li><li><a href="index.html#5">Chapter 5: Services for the Inform Compiler</a></li><li><b>Source Text</b></li></ul><p class="purpose">Code for reading Inform 7 source text, which Inbuild uses for both extensions and projects.</p>
<p class="inwebparagraph"><a id="SP1"></a><b>&#167;1. </b>This short function is a bridge to the lexer, and is used for reading
text files of source into either projects or extensions. Note that it
doesn't attach the fed text to the copy: the copy may need to contain text
from multiple files and indeed from elsewhere.
</p>
<pre class="display">
<span class="reserved">inbuild_copy</span><span class="plain"> *</span><span class="identifier">currently_lexing_into</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="identifier">source_file</span><span class="plain"> *</span><span class="functiontext">SourceText::read_file</span><span class="plain">(</span><span class="reserved">inbuild_copy</span><span class="plain"> *</span><span class="identifier">C</span><span class="plain">, </span><span class="identifier">filename</span><span class="plain"> *</span><span class="identifier">F</span><span class="plain">, </span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">synopsis</span><span class="plain">,</span>
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">documentation_only</span><span class="plain">, </span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">primary</span><span class="plain">) {</span>
<span class="identifier">currently_lexing_into</span><span class="plain"> = </span><span class="identifier">C</span><span class="plain">;</span>
<span class="identifier">general_pointer</span><span class="plain"> </span><span class="identifier">ref</span><span class="plain"> = </span><span class="identifier">STORE_POINTER_inbuild_copy</span><span class="plain">(</span><span class="identifier">NULL</span><span class="plain">);</span>
<span class="reserved">FILE</span><span class="plain"> *</span><span class="identifier">handle</span><span class="plain"> = </span><span class="identifier">Filenames::fopen</span><span class="plain">(</span><span class="identifier">F</span><span class="plain">, </span><span class="string">"r"</span><span class="plain">);</span>
<span class="identifier">source_file</span><span class="plain"> *</span><span class="identifier">sf</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">handle</span><span class="plain">) {</span>
<span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">leaf</span><span class="plain"> = </span><span class="identifier">Filenames::get_leafname</span><span class="plain">(</span><span class="identifier">F</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">primary</span><span class="plain">) </span><span class="identifier">leaf</span><span class="plain"> = </span><span class="identifier">I</span><span class="string">"main source text"</span><span class="plain">;</span>
<span class="identifier">sf</span><span class="plain"> = </span><span class="identifier">TextFromFiles::feed_open_file_into_lexer</span><span class="plain">(</span><span class="identifier">F</span><span class="plain">, </span><span class="identifier">handle</span><span class="plain">,</span>
<span class="identifier">leaf</span><span class="plain">, </span><span class="identifier">documentation_only</span><span class="plain">, </span><span class="identifier">ref</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">sf</span><span class="plain"> == </span><span class="identifier">NULL</span><span class="plain">) {</span>
<span class="functiontext">Copies::attach</span><span class="plain">(</span><span class="identifier">C</span><span class="plain">, </span><span class="functiontext">Copies::new_error_on_file</span><span class="plain">(</span><span class="constant">OPEN_FAILED_CE</span><span class="plain">, </span><span class="identifier">F</span><span class="plain">));</span>
<span class="plain">} </span><span class="reserved">else</span><span class="plain"> {</span>
<span class="identifier">fclose</span><span class="plain">(</span><span class="identifier">handle</span><span class="plain">);</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">documentation_only</span><span class="plain"> == </span><span class="identifier">FALSE</span><span class="plain">) </span>&lt;<span class="cwebmacro">Tell console output about the file</span> <span class="cwebmacronumber">1.1</span>&gt;<span class="plain">;</span>
<span class="plain">}</span>
<span class="plain">}</span>
<span class="identifier">currently_lexing_into</span><span class="plain"> = </span><span class="identifier">NULL</span><span class="plain">;</span>
<span class="reserved">return</span><span class="plain"> </span><span class="identifier">sf</span><span class="plain">;</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function SourceText::read_file is used in 5/es (<a href="5-es.html#SP5">&#167;5</a>), 5/ps (<a href="5-ps.html#SP4">&#167;4</a>).</p>
<p class="inwebparagraph"><a id="SP1_1"></a><b>&#167;1.1. </b>This is where messages like
</p>
<p class="inwebparagraph"></p>
<pre class="display">
<span class="plain">I've also read Standard Rules by Graham Nelson, which is 27204 words long.</span>
</pre>
<p class="inwebparagraph">are printed to <code class="display"><span class="extract">stdout</span></code> (not <code class="display"><span class="extract">stderr</span></code>), in something of an affectionate nod
to TeX's traditional console output, though occasionally I think silence is
golden and that these messages could go. It's a moot point for almost all users,
though, because the console output is concealed from them by the Inform
application.
</p>
<p class="macrodefinition"><code class="display">
&lt;<span class="cwebmacrodefn">Tell console output about the file</span> <span class="cwebmacronumber">1.1</span>&gt; =
</code></p>
<pre class="displaydefn">
<span class="reserved">int</span><span class="plain"> </span><span class="identifier">wc</span><span class="plain">;</span>
<span class="reserved">char</span><span class="plain"> *</span><span class="identifier">message</span><span class="plain">;</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">primary</span><span class="plain">) </span><span class="identifier">message</span><span class="plain"> = </span><span class="string">"I've now read %S, which is %d words long.\</span><span class="plain">n</span><span class="string">"</span><span class="plain">;</span>
<span class="reserved">else</span><span class="plain"> </span><span class="identifier">message</span><span class="plain"> = </span><span class="string">"I've also read %S, which is %d words long.\</span><span class="plain">n</span><span class="string">"</span><span class="plain">;</span>
<span class="identifier">wc</span><span class="plain"> = </span><span class="identifier">TextFromFiles::total_word_count</span><span class="plain">(</span><span class="identifier">sf</span><span class="plain">);</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">STDOUT</span><span class="plain">, </span><span class="identifier">message</span><span class="plain">, </span><span class="identifier">synopsis</span><span class="plain">, </span><span class="identifier">wc</span><span class="plain">);</span>
<span class="identifier">STREAM_FLUSH</span><span class="plain">(</span><span class="identifier">STDOUT</span><span class="plain">);</span>
<span class="identifier">LOG</span><span class="plain">(</span><span class="identifier">message</span><span class="plain">, </span><span class="identifier">synopsis</span><span class="plain">, </span><span class="identifier">wc</span><span class="plain">);</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">This code is used in <a href="#SP1">&#167;1</a>.</p>
<p class="inwebparagraph"><a id="SP2"></a><b>&#167;2. </b></p>
<pre class="definitions">
<span class="definitionkeyword">define</span> <span class="constant">LEXER_PROBLEM_HANDLER</span><span class="plain"> </span><span class="functiontext">SourceText::lexer_problem_handler</span>
</pre>
<pre class="display">
<span class="reserved">void</span><span class="plain"> </span><span class="functiontext">SourceText::lexer_problem_handler</span><span class="plain">(</span><span class="reserved">int</span><span class="plain"> </span><span class="identifier">err</span><span class="plain">, </span><span class="identifier">text_stream</span><span class="plain"> *</span><span class="identifier">desc</span><span class="plain">, </span><span class="identifier">wchar_t</span><span class="plain"> *</span><span class="identifier">word</span><span class="plain">) {</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">err</span><span class="plain"> == </span><span class="identifier">MEMORY_OUT_LEXERERROR</span><span class="plain">)</span>
<span class="identifier">Errors::fatal</span><span class="plain">(</span><span class="string">"Out of memory: unable to create lexer workspace"</span><span class="plain">);</span>
<span class="identifier">TEMPORARY_TEXT</span><span class="plain">(</span><span class="identifier">erm</span><span class="plain">);</span>
<span class="reserved">switch</span><span class="plain"> (</span><span class="identifier">err</span><span class="plain">) {</span>
<span class="reserved">case</span><span class="plain"> </span><span class="identifier">STRING_TOO_LONG_LEXERERROR</span><span class="plain">:</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">erm</span><span class="plain">, </span><span class="string">"Too much text in quotation marks: %w"</span><span class="plain">, </span><span class="identifier">word</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="identifier">WORD_TOO_LONG_LEXERERROR</span><span class="plain">:</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">erm</span><span class="plain">, </span><span class="string">"Word too long: %w"</span><span class="plain">, </span><span class="identifier">word</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="identifier">I6_TOO_LONG_LEXERERROR</span><span class="plain">:</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">erm</span><span class="plain">, </span><span class="string">"I6 inclusion too long: %w"</span><span class="plain">, </span><span class="identifier">word</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="identifier">STRING_NEVER_ENDS_LEXERERROR</span><span class="plain">:</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">erm</span><span class="plain">, </span><span class="string">"Quoted text never ends: %S"</span><span class="plain">, </span><span class="identifier">desc</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="identifier">COMMENT_NEVER_ENDS_LEXERERROR</span><span class="plain">:</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">erm</span><span class="plain">, </span><span class="string">"Square-bracketed text never ends: %S"</span><span class="plain">, </span><span class="identifier">desc</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="identifier">I6_NEVER_ENDS_LEXERERROR</span><span class="plain">:</span>
<span class="identifier">WRITE_TO</span><span class="plain">(</span><span class="identifier">erm</span><span class="plain">, </span><span class="string">"I6 inclusion text never ends: %S"</span><span class="plain">, </span><span class="identifier">desc</span><span class="plain">);</span>
<span class="reserved">break</span><span class="plain">;</span>
<span class="reserved">default</span><span class="plain">:</span>
<span class="identifier">internal_error</span><span class="plain">(</span><span class="string">"unknown lexer error"</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="reserved">if</span><span class="plain"> (</span><span class="identifier">currently_lexing_into</span><span class="plain">) {</span>
<span class="reserved">copy_error</span><span class="plain"> *</span><span class="identifier">CE</span><span class="plain"> = </span><span class="functiontext">Copies::new_error</span><span class="plain">(</span><span class="constant">LEXER_CE</span><span class="plain">, </span><span class="identifier">erm</span><span class="plain">);</span>
<span class="identifier">CE</span><span class="plain">-</span><span class="element">&gt;error_subcategory</span><span class="plain"> = </span><span class="identifier">err</span><span class="plain">;</span>
<span class="identifier">CE</span><span class="plain">-</span><span class="element">&gt;details</span><span class="plain"> = </span><span class="identifier">Str::duplicate</span><span class="plain">(</span><span class="identifier">desc</span><span class="plain">);</span>
<span class="identifier">CE</span><span class="plain">-</span><span class="element">&gt;word</span><span class="plain"> = </span><span class="identifier">word</span><span class="plain">;</span>
<span class="functiontext">Copies::attach</span><span class="plain">(</span><span class="identifier">currently_lexing_into</span><span class="plain">, </span><span class="identifier">CE</span><span class="plain">);</span>
<span class="plain">}</span>
<span class="identifier">DISCARD_TEXT</span><span class="plain">(</span><span class="identifier">erm</span><span class="plain">);</span>
<span class="plain">}</span>
</pre>
<p class="inwebparagraph"></p>
<p class="endnote">The function SourceText::lexer_problem_handler appears nowhere else.</p>
<hr class="tocbar">
<ul class="toc"><li><i>(This section begins Chapter 5: Services for the Inform Compiler.)</i></li><li><a href="5-vmg.html">Continue with 'Virtual Machine Grammar'</a></li></ul><hr class="tocbar">
<!--End of weave-->
</body>
</html>