commit 725ec0f963b78bf56c86d7d12b351855faaa7100
parent ce52e31de4a29305137089047e8ca68237b72b3e
Author: Andres Navarro <canavarro82@gmail.com>
Date: Fri, 3 Jun 2011 16:09:59 -0300
Completed the ports section of the manual.
Diffstat:
5 files changed, 812 insertions(+), 4 deletions(-)
diff --git a/manual/html/Index.html b/manual/html/Index.html
@@ -55,6 +55,7 @@ Up: <a rel="up" accesskey="u" href="index.html#Top">Top</a>
<li><a href="Control.html#index-g_t_0024sequence-30"><code>$sequence</code></a>: <a href="Control.html#Control">Control</a></li>
<li><a href="Environments.html#index-g_t_0024set_0021-111"><code>$set!</code></a>: <a href="Environments.html#Environments">Environments</a></li>
<li><a href="Combiners.html#index-g_t_0024vau-119"><code>$vau</code></a>: <a href="Combiners.html#Combiners">Combiners</a></li>
+<li><a href="Ports.html#index-g_t_0028-157"><code>(</code></a>: <a href="Ports.html#Ports">Ports</a></li>
<li><a href="Continuations.html#index-g_t_0028-135"><code>(</code></a>: <a href="Continuations.html#Continuations">Continuations</a></li>
<li><a href="Environments.html#index-g_t_0028-110"><code>(</code></a>: <a href="Environments.html#Environments">Environments</a></li>
<li><a href="Booleans.html#index-and_003f-15"><code>and?</code></a>: <a href="Booleans.html#Booleans">Booleans</a></li>
@@ -83,6 +84,8 @@ Up: <a rel="up" accesskey="u" href="index.html#Top">Top</a>
<li><a href="Pairs-and-lists.html#index-cadddr-66"><code>cadddr</code></a>: <a href="Pairs-and-lists.html#Pairs-and-lists">Pairs and lists</a></li>
<li><a href="Pairs-and-lists.html#index-caddr-54"><code>caddr</code></a>: <a href="Pairs-and-lists.html#Pairs-and-lists">Pairs and lists</a></li>
<li><a href="Pairs-and-lists.html#index-cadr-48"><code>cadr</code></a>: <a href="Pairs-and-lists.html#Pairs-and-lists">Pairs and lists</a></li>
+<li><a href="Ports.html#index-call_002dwith_002dinput_002dfile-167"><code>call-with-input-file</code></a>: <a href="Ports.html#Ports">Ports</a></li>
+<li><a href="Ports.html#index-call_002dwith_002doutput_002dfile-168"><code>call-with-output-file</code></a>: <a href="Ports.html#Ports">Ports</a></li>
<li><a href="Continuations.html#index-call_002fcc-128"><code>call/cc</code></a>: <a href="Continuations.html#Continuations">Continuations</a></li>
<li><a href="Pairs-and-lists.html#index-car-45"><code>car</code></a>: <a href="Pairs-and-lists.html#Pairs-and-lists">Pairs and lists</a></li>
<li><a href="Pairs-and-lists.html#index-cdaaar-67"><code>cdaaar</code></a>: <a href="Pairs-and-lists.html#Pairs-and-lists">Pairs and lists</a></li>
@@ -118,6 +121,7 @@ Up: <a rel="up" accesskey="u" href="index.html#Top">Top</a>
<li><a href="Pairs-and-lists.html#index-encycle_0021-77"><code>encycle!</code></a>: <a href="Pairs-and-lists.html#Pairs-and-lists">Pairs and lists</a></li>
<li><a href="Environments.html#index-environment_003f-95"><code>environment?</code></a>: <a href="Environments.html#Environments">Environments</a></li>
<li><a href="Environments.html#index-environments-93">environments</a>: <a href="Environments.html#Environments">Environments</a></li>
+<li><a href="Ports.html#index-eof_002dobject_003f-171"><code>eof-object?</code></a>: <a href="Ports.html#Ports">Ports</a></li>
<li><a href="Equivalence.html#index-eq_003f-20"><code>eq?</code></a>: <a href="Equivalence.html#Equivalence">Equivalence</a></li>
<li><a href="Equivalence.html#index-equal_003f-21"><code>equal?</code></a>: <a href="Equivalence.html#Equivalence">Equivalence</a></li>
<li><a href="Equivalence.html#index-equivalence-19">equivalence</a>: <a href="Equivalence.html#Equivalence">Equivalence</a></li>
@@ -135,12 +139,14 @@ Up: <a rel="up" accesskey="u" href="index.html#Top">Top</a>
<li><a href="Promises.html#index-force-142"><code>force</code></a>: <a href="Promises.html#Promises">Promises</a></li>
<li><a href="Environments.html#index-get_002dcurrent_002denvironment-102"><code>get-current-environment</code></a>: <a href="Environments.html#Environments">Environments</a></li>
<li><a href="Pairs-and-lists.html#index-get_002dlist_002dmetrics-75"><code>get-list-metrics</code></a>: <a href="Pairs-and-lists.html#Pairs-and-lists">Pairs and lists</a></li>
+<li><a href="Ports.html#index-get_002dmodule-170"><code>get-module</code></a>: <a href="Ports.html#Ports">Ports</a></li>
<li><a href="Continuations.html#index-guard_002dcontinuation-130"><code>guard-continuation</code></a>: <a href="Continuations.html#Continuations">Continuations</a></li>
<li><a href="Continuations.html#index-guard_002ddynamic_002dextent-136"><code>guard-dynamic-extent</code></a>: <a href="Continuations.html#Continuations">Continuations</a></li>
<li><a href="Environments.html#index-ignore-94">ignore</a>: <a href="Environments.html#Environments">Environments</a></li>
<li><a href="Environments.html#index-ignore_003f-96"><code>ignore?</code></a>: <a href="Environments.html#Environments">Environments</a></li>
<li><a href="Control.html#index-inert-27">inert</a>: <a href="Control.html#Control">Control</a></li>
<li><a href="Control.html#index-inert_003f-28"><code>inert?</code></a>: <a href="Control.html#Control">Control</a></li>
+<li><a href="Ports.html#index-input_002dport_003f-155"><code>input-port?</code></a>: <a href="Ports.html#Ports">Ports</a></li>
<li><a href="Kernel-History.html#index-Kernel-history-1">Kernel history</a>: <a href="Kernel-History.html#Kernel-History">Kernel History</a></li>
<li><a href="Keyed-Variables.html#index-keyed-dynamic-variables-146">keyed dynamic variables</a>: <a href="Keyed-Variables.html#Keyed-Variables">Keyed Variables</a></li>
<li><a href="Keyed-Variables.html#index-keyed-static-variables-148">keyed static variables</a>: <a href="Keyed-Variables.html#Keyed-Variables">Keyed Variables</a></li>
@@ -152,6 +158,7 @@ Up: <a rel="up" accesskey="u" href="index.html#Top">Top</a>
<li><a href="Pairs-and-lists.html#index-list_002dref-80"><code>list-ref</code></a>: <a href="Pairs-and-lists.html#Pairs-and-lists">Pairs and lists</a></li>
<li><a href="Pairs-and-lists.html#index-list_002dtail-76"><code>list-tail</code></a>: <a href="Pairs-and-lists.html#Pairs-and-lists">Pairs and lists</a></li>
<li><a href="Pairs-and-lists.html#index-lists-36">lists</a>: <a href="Pairs-and-lists.html#Pairs-and-lists">Pairs and lists</a></li>
+<li><a href="Ports.html#index-load-169"><code>load</code></a>: <a href="Ports.html#Ports">Ports</a></li>
<li><a href="Encapsulations.html#index-make_002dencapsulation_002dtype-139"><code>make-encapsulation-type</code></a>: <a href="Encapsulations.html#Encapsulations">Encapsulations</a></li>
<li><a href="Environments.html#index-make_002denvironment-98"><code>make-environment</code></a>: <a href="Environments.html#Environments">Environments</a></li>
<li><a href="Environments.html#index-make_002dkernel_002dstandard_002denvironment-103"><code>make-kernel-standard-environment</code></a>: <a href="Environments.html#Environments">Environments</a></li>
@@ -167,16 +174,21 @@ Up: <a rel="up" accesskey="u" href="index.html#Top">Top</a>
<li><a href="Pairs-and-lists.html#index-null_003f-38"><code>null?</code></a>: <a href="Pairs-and-lists.html#Pairs-and-lists">Pairs and lists</a></li>
<li><a href="Numbers.html#index-numbers-150">numbers</a>: <a href="Numbers.html#Numbers">Numbers</a></li>
<li><a href="A-Sample-Applicative-Description.html#index-object-descriptions-10">object descriptions</a>: <a href="A-Sample-Applicative-Description.html#A-Sample-Applicative-Description">A Sample Applicative Description</a></li>
+<li><a href="Ports.html#index-open_002dinput_002dfile-161"><code>open-input-file</code></a>: <a href="Ports.html#Ports">Ports</a></li>
+<li><a href="Ports.html#index-open_002doutput_002dfile-162"><code>open-output-file</code></a>: <a href="Ports.html#Ports">Ports</a></li>
<li><a href="A-Sample-Applicative-Description.html#index-operative-descriptions-9">operative descriptions</a>: <a href="A-Sample-Applicative-Description.html#A-Sample-Applicative-Description">A Sample Applicative Description</a></li>
<li><a href="Combiners.html#index-operative_003f-117"><code>operative?</code></a>: <a href="Combiners.html#Combiners">Combiners</a></li>
<li><a href="Combiners.html#index-operatives-116">operatives</a>: <a href="Combiners.html#Combiners">Combiners</a></li>
<li><a href="Booleans.html#index-or_003f-16"><code>or?</code></a>: <a href="Booleans.html#Booleans">Booleans</a></li>
+<li><a href="Ports.html#index-output_002dport_003f-156"><code>output-port?</code></a>: <a href="Ports.html#Ports">Ports</a></li>
<li><a href="Pairs-and-lists.html#index-pair_003f-37"><code>pair?</code></a>: <a href="Pairs-and-lists.html#Pairs-and-lists">Pairs and lists</a></li>
<li><a href="Pairs-and-lists.html#index-pairs-33">pairs</a>: <a href="Pairs-and-lists.html#Pairs-and-lists">Pairs and lists</a></li>
+<li><a href="Ports.html#index-port_003f-154"><code>port?</code></a>: <a href="Ports.html#Ports">Ports</a></li>
<li><a href="Ports.html#index-ports-153">ports</a>: <a href="Ports.html#Ports">Ports</a></li>
<li><a href="Printing-Notation.html#index-printing-notation-5">printing notation</a>: <a href="Printing-Notation.html#Printing-Notation">Printing Notation</a></li>
<li><a href="Promises.html#index-promise_003f-141"><code>promise?</code></a>: <a href="Promises.html#Promises">Promises</a></li>
<li><a href="Promises.html#index-promises-140">promises</a>: <a href="Promises.html#Promises">Promises</a></li>
+<li><a href="Ports.html#index-read-165"><code>read</code></a>: <a href="Ports.html#Ports">Ports</a></li>
<li><a href="Pairs-and-lists.html#index-reduce-88"><code>reduce</code></a>: <a href="Pairs-and-lists.html#Pairs-and-lists">Pairs and lists</a></li>
<li><a href="Continuations.html#index-root_002dcontinuation-132"><code>root-continuation</code></a>: <a href="Continuations.html#Continuations">Continuations</a></li>
<li><a href="Pairs-and-lists.html#index-set_002dcar_0021-40"><code>set-car!</code></a>: <a href="Pairs-and-lists.html#Pairs-and-lists">Pairs and lists</a></li>
diff --git a/manual/html/Ports.html b/manual/html/Ports.html
@@ -35,9 +35,290 @@ Up: <a rel="up" accesskey="u" href="index.html#Top">Top</a>
<h2 class="chapter">16 Ports</h2>
<p><a name="index-ports-153"></a>
+ A port is an object that mediates character-based input from a
+source or character-based output to a destination. In the former case,
+the port is an input port, in the latter case, an output port.
+
+<!-- TODO add xref to equal? & eq? -->
+ <p>Although ports are not considered immutable, none of the operations
+on ports described in this section constitute mutation. Ports are
+<code>equal?</code> iff <code>eq?</code>. The port type is encapsulated.
+
+ <p>An auxiliary data type used to signal the end of file was reached is
+eof. The eof type consists of a single immutable value, having
+an output only external representation (so that it can never be the
+normal result of a call to read). The eof type is encapsulated.
+
+ <p>SOURCE NOTE: the eof type is not in the Kernel report, it is used in
+klisp and was taken from Scheme.
+
+<div class="defun">
+— Applicative: <b>port?</b> (<var>port? . objects</var>)<var><a name="index-port_003f-154"></a></var><br>
+<blockquote><p> The primitive type predicate for type port. <code>port?</code>
+returns true iff all the objects in <code>objects</code> are of type port.
+</p></blockquote></div>
+
+<div class="defun">
+— Applicative: <b>input-port?</b> (<var>input-port? . objects</var>)<var><a name="index-input_002dport_003f-155"></a></var><br>
+— Applicative: <b>output-port?</b> (<var>output-port? . objects</var>)<var><a name="index-output_002dport_003f-156"></a></var><br>
+<blockquote><p> Applicative <code>input-port?</code> is a predicate that returns true
+unless one or more of its arguments is not an input port. Applicative
+output-port? is a predicate that returns true unless one or more of
+its arguments is not an output port.
+
+ <p>Every port must be admitted by at least one of these two predicates.
+</p></blockquote></div>
+
+<div class="defun">
+— with-input-from-file: <b>(</b><var>with-input-from-file string combiner</var>)<var><a name="index-g_t_0028-157"></a></var><br>
+— with-output-to-file: <b>(</b><var>with-output-to-file string combiner</var>)<var><a name="index-g_t_0028-158"></a></var><br>
+<blockquote><!-- add xref get-current-input-port/get-current-output-port -->
+ <p>These two applicatives open the file named in <code>string</code> for
+input or output, an invoke the binder of the input-port & output-port
+keyed dynamic variables respectively with the opened port & the passed
+<code>combiner</code> (this means that the combiner is called in a fresh, empty
+dynamic environment). When/if the binder normally returns, the port is closed.
+The result of the applicatives <code>with-input-from-file</code> and
+<code>with-output-from-file</code> is inert.
+
+ <p>SOURCE NOTE: this is enumerated in the Kernel report but the text is
+still missing. In the new scheme report there's also a third
+error-port variable. It is very likely that that will be added to the
+klisp implementation in the near future.
+</p></blockquote></div>
+
+<div class="defun">
+— get-current-input-port: <b>(</b><var>get-current-input-port</var>)<var><a name="index-g_t_0028-159"></a></var><br>
+— get-current-output-port: <b>(</b><var>get-current-output-port</var>)<var><a name="index-g_t_0028-160"></a></var><br>
+<blockquote><p> These are the accessors for the input-port and output-port keyed
+dynamic variables repectively.
+<!-- add xref to with-input-from-file, etc -->
+<!-- add xref and text for these dynamic vars -->
+
+ <p>SOURCE NOTE: this is enumerated in the Kernel report but the text is
+still missing. In the new scheme report there's also a third
+error-port variable. It is very likely that that will be added to the
+klisp implementation in the near future.
+</p></blockquote></div>
+
+<div class="defun">
+— Applicative: <b>open-input-file</b> (<var>open-input-file string</var>)<var><a name="index-open_002dinput_002dfile-161"></a></var><br>
+<blockquote><p> <code>string</code> should be the name/path for an existing file.
+
+ <p>Applicative <code>open-input-file</code> creates and returns an input port
+associated with the file represented with <code>string</code>. If the file
+can't be opened (e.g. because it doesn't exists, or there's a
+permissions problem), an error is signaled.
+
+ <p>SOURCE NOTE: this is enumerated in the Kernel report but the text is
+still missing.
+</p></blockquote></div>
+
+<div class="defun">
+— Applicative: <b>open-output-file</b> (<var>open-output-file string</var>)<var><a name="index-open_002doutput_002dfile-162"></a></var><br>
+<blockquote><p> <code>string</code> should be the name/path for an existing file.
+
+ <p>Applicative <code>open-output-file</code> creates and returns an output
+port associated with the file represented with <code>string</code>. If the
+file can't be opened (e.g. if there's a permissions problem), an error
+is signaled.
+
+ <p>In klisp, for now, applicative <code>open-output-file</code> truncates the
+file if it already exists, but that could change later (i.e. like in
+scheme the behaviour should be considered unspecified).
+
+ <p>SOURCE NOTE: this is enumerated in the Kernel report but the text is
+still missing.
+</p></blockquote></div>
+
+<div class="defun">
+— close-input-file: <b>(</b><var>close-input-file input-port</var>)<var><a name="index-g_t_0028-163"></a></var><br>
+— close-output-file: <b>(</b><var>close-output-file output-port</var>)<var><a name="index-g_t_0028-164"></a></var><br>
+<blockquote><p> These applicatives close the port argument, so that no more
+input/output may be performed on them, and the resources can be
+freed. If the port was already closed these applicatives have no
+effect.
+
+ <p>The result returned by applicatives <code>close-input-file</code> and
+<code>close-output-file</code> is inert.
+
+ <p>SOURCE NOTE: this is enumerated in the Kernel report but the text is
+still missing. There's probably a name error here. These should
+probably be called close-input-port & close-output-port.
+</p></blockquote></div>
+
+<div class="defun">
+— Applicative: <b>read</b> (<var>read </var>[<var>input-port</var>])<var><a name="index-read-165"></a></var><br>
+<blockquote><p> If the <code>port</code> optional argument is not specified, then the
+value of the <code>input-port</code> keyed dynamic variable is used. If the
+port is closed, an error is signaled.
+
+ <p>Applicative <code>read</code> reads & returns the next parseable object
+from the given port, or the eof object if no objects remain. If
+<code>read</code> finds and unparseable object in the port, an error is
+signaled. In that case, the remaining position in the port is
+unspecified.
+
+ <p>SOURCE NOTE: this is enumerated in the Kernel report but the text is
+still missing.
+</p></blockquote></div>
+
+<div class="defun">
+— write: <b>(</b><var>write object </var>[<var>port</var>])<var><a name="index-g_t_0028-166"></a></var><br>
+<blockquote><p> If the <code>port</code> optional argument is not specified, then the
+value of the <code>output-port</code> keyed dynamic variable is used. If the
+port is closed, an error is signaled.
+
+ <!-- TODO add xref to external representation -->
+ <p>Applicative <code>write</code> writes an external representation of
+<code>object</code> to the specified port. This may be an output-only
+representation that can't be read by applicative <code>read</code> in cases
+where the type of <code>object</code> doen't have a parseable external
+representation (e.g. combiners and environments). The result returned
+by <code>write</code> is inert.
+
+ <p>SOURCE NOTE: this is enumerated in the Kernel report but the text is
+still missing.
+</p></blockquote></div>
+
+<div class="defun">
+— Applicative: <b>call-with-input-file</b> (<var>call-with-input-file string combiner</var>)<var><a name="index-call_002dwith_002dinput_002dfile-167"></a></var><br>
+— Applicative: <b>call-with-output-file</b> (<var>call-with-output-file string combiner</var>)<var><a name="index-call_002dwith_002doutput_002dfile-168"></a></var><br>
+<blockquote><p> These applicatives open file named in <code>string</code> and call their
+<code>combiner</code> argument in a fresh empty environment passing it as a
+sole operand the opened port. When/if the combiner normally returns a
+value the port is closed and that value is returned as the result of
+the applicative.
+
+ <p>SOURCE NOTE: this is enumerated in the Kernel report but the text is
+still missing.
+</p></blockquote></div>
+
+<div class="defun">
+— Applicative: <b>load</b> (<var>load string</var>)<var><a name="index-load-169"></a></var><br>
+<blockquote><!-- TODO add xref, open/input, read -->
+ <p>Applicative <code>load</code> opens for input a file named <code>string</code>;
+reads objects from the file until the end of the file is reached;
+evaluates those objects consecutively in the created environment. The
+result from applicative <code>load</code> is inert.
+
+ <p>SOURCE NOTE: load is enumerated in the Kernel report, but the
+description is not there yet. This seems like a sane way to define
+it, taking the description of <code>get-module</code> that there is in the
+report. The one detail that I think is still open, is whether to
+return <code>#inert</code> (as is the case with klisp currently) or rather
+return the value of the last evaluation.
+</p></blockquote></div>
+
+<div class="defun">
+— Applicative: <b>get-module</b> (<var>get-module string </var>[<var>environment</var>])<var><a name="index-get_002dmodule-170"></a></var><br>
+<blockquote><!-- TODO add xref standard-environment, open/input, read -->
+ <p>Applicative <code>get-module</code> creates a fresh standard environment;
+opens for input a file named <code>string</code>; reads objects from the
+file until the end of the file is reached; evaluates those objects
+consecutively in the created environment; and, lastly, returns the
+created environment. If the optional argument <code>environment</code> is
+specified, the freshly created standard environment is augmented,
+prior to evaluating read expressions, by binding symbol
+<code>module-parameters</code> to the <code>environment</code> argument.
+</p></blockquote></div>
+
+<div class="defun">
+— Applicative: <b>eof-object?</b> (<var>eof-object? . objects</var>)<var><a name="index-eof_002dobject_003f-171"></a></var><br>
+<blockquote><p> The primitive type predicate for type eof. <code>eof-object?</code>
+returns true iff all the objects in <code>objects</code> are of type eof.
+
+ <p>SOURCE NOTE: This is not in the report, the idea is from Scheme.
+The <code>eof-object?</code> name is also from scheme, but this will
+probably be changed to just <code>eof?</code>, for consistency with the other
+primitive type predicates.
+</p></blockquote></div>
+
+<div class="defun">
+— read-char: <b>(</b><var>read-char </var>[<var>port</var>])<var><a name="index-g_t_0028-172"></a></var><br>
+<blockquote><p> If the <code>port</code> optional argument is not specified, then the
+value of the <code>input-port</code> keyed dynamic variable is used. If the
+port is closed, an error is signaled.
+
+ <p>Applicative <code>read-char</code> reads and returns a character (not
+an external representation of a character) from the specified port, or
+an eof if the end of file was reached.
+
+ <p>SOURCE NOTE: this is missing from Kernel, it is taken from Scheme.
+</p></blockquote></div>
+
+<div class="defun">
+— peek-char: <b>(</b><var>peek-char </var>[<var>port</var>])<var><a name="index-g_t_0028-173"></a></var><br>
+<blockquote><p> If the <code>port</code> optional argument is not specified, then the
+value of the <code>input-port</code> keyed dynamic variable is used. If the
+port is closed, an error is signaled.
+
+ <p>Applicative <code>peek-char</code> reads and returns a character (not
+an external representation of a character) from the specified port, or
+an eof if the end of file was reached. The position of the port
+remains unchanged so that new call to <code>peek-char</code> or
+<code>read-char</code> on the same port return the same character.
+
+ <p>SOURCE NOTE: this is missing from Kernel, it is taken from Scheme.
+</p></blockquote></div>
+
+<div class="defun">
+— char-ready?: <b>(</b><var>char-ready? </var>[<var>port</var>])<var><a name="index-g_t_0028-174"></a></var><br>
+<blockquote><p> If the <code>port</code> optional argument is not specified, then the
+value of the <code>input-port</code> keyed dynamic variable is used. If the
+port is closed, an error is signaled.
+
+ <p>Predicate <code>char-ready?</code> checks to see if a character is
+available in the specified port. If it returns true, then a
+<code>read-char</code> or <code>peek-char</code> on that port is guaranteed not to
+block/hang. For now in klisp this is hardcoded to <code>#t</code> because
+the code to do this is non-portable.
+
+ <p>SOURCE NOTE: this is missing from Kernel, it is taken from Scheme.
+</p></blockquote></div>
+
+<div class="defun">
+— write-char: <b>(</b><var>write-char char </var>[<var>port</var>])<var><a name="index-g_t_0028-175"></a></var><br>
+<blockquote><p> If the <code>port</code> optional argument is not specified, then the
+value of the <code>output-port</code> keyed dynamic variable is used. If the
+port is closed, an error is signaled.
+
+ <p>Applicative <code>write-char</code> writes the <code>char</code> character (not
+an external representation of the character) to the specified port.
+The result returned by <code>write-char</code> is inert.
+
+ <p>SOURCE NOTE: this is missing from Kernel, it is taken from Scheme.
+</p></blockquote></div>
+
+<div class="defun">
+— newline: <b>(</b><var>newline </var>[<var>port</var>])<var><a name="index-g_t_0028-176"></a></var><br>
+<blockquote><p> If the <code>port</code> optional argument is not specified, then the
+value of the <code>output-port</code> keyed dynamic variable is used. If the
+port is closed, an error is signaled.
+
+ <p>Applicative <code>newline</code> writes a newline to the specified port.
+The result returned by <code>newline</code> is inert.
+
+ <p>SOURCE NOTE: this is missing from Kernel, it is taken from Scheme.
+</p></blockquote></div>
+
+<div class="defun">
+— display: <b>(</b><var>display object </var>[<var>port</var>])<var><a name="index-g_t_0028-177"></a></var><br>
+<blockquote><p> If the <code>port</code> optional argument is not specified, then the
+value of the <code>output-port</code> keyed dynamic variable is used. If the
+port is closed, an error is signaled.
+
+ <p>Applicative <code>display</code> behaves like <code>write</code> except that
+strings are not enclosed in double quotes and no character is escaped
+within those strings and character objects are output as if by
+<code>write-char</code> instead of <code>read</code>. The result returned by
+<code>display</code> is inert.
+
+ <p>SOURCE NOTE: this is missing from Kernel, it is taken from Scheme.
+</p></blockquote></div>
+
<!-- appendices -->
<!-- TODO -->
-
<!-- *-texinfo-*- -->
<!-- TODO correct prev node -->
</body></html>
diff --git a/manual/klisp.info b/manual/klisp.info
@@ -1583,6 +1583,245 @@ File: klisp.info, Node: Ports, Next: Index, Prev: Characters, Up: Top
16 Ports
********
+A port is an object that mediates character-based input from a source
+or character-based output to a destination. In the former case, the
+port is an input port, in the latter case, an output port.
+
+ Although ports are not considered immutable, none of the operations
+on ports described in this section constitute mutation. Ports are
+`equal?' iff `eq?'. The port type is encapsulated.
+
+ An auxiliary data type used to signal the end of file was reached is
+eof. The eof type consists of a single immutable value, having an
+output only external representation (so that it can never be the normal
+result of a call to read). The eof type is encapsulated.
+
+ SOURCE NOTE: the eof type is not in the Kernel report, it is used in
+klisp and was taken from Scheme.
+
+ -- Applicative: port? (port? . objects)
+ The primitive type predicate for type port. `port?' returns true
+ iff all the objects in `objects' are of type port.
+
+ -- Applicative: input-port? (input-port? . objects)
+ -- Applicative: output-port? (output-port? . objects)
+ Applicative `input-port?' is a predicate that returns true unless
+ one or more of its arguments is not an input port. Applicative
+ output-port? is a predicate that returns true unless one or more of
+ its arguments is not an output port.
+
+ Every port must be admitted by at least one of these two
+ predicates.
+
+ -- with-input-from-file: (with-input-from-file string combiner)
+ -- with-output-to-file: (with-output-to-file string combiner)
+ These two applicatives open the file named in `string' for input
+ or output, an invoke the binder of the input-port & output-port
+ keyed dynamic variables respectively with the opened port & the
+ passed `combiner' (this means that the combiner is called in a
+ fresh, empty dynamic environment). When/if the binder normally
+ returns, the port is closed. The result of the applicatives
+ `with-input-from-file' and `with-output-from-file' is inert.
+
+ SOURCE NOTE: this is enumerated in the Kernel report but the text
+ is still missing. In the new scheme report there's also a third
+ error-port variable. It is very likely that that will be added to
+ the klisp implementation in the near future.
+
+ -- get-current-input-port: (get-current-input-port)
+ -- get-current-output-port: (get-current-output-port)
+ These are the accessors for the input-port and output-port keyed
+ dynamic variables repectively.
+
+ SOURCE NOTE: this is enumerated in the Kernel report but the text
+ is still missing. In the new scheme report there's also a third
+ error-port variable. It is very likely that that will be added to
+ the klisp implementation in the near future.
+
+ -- Applicative: open-input-file (open-input-file string)
+ `string' should be the name/path for an existing file.
+
+ Applicative `open-input-file' creates and returns an input port
+ associated with the file represented with `string'. If the file
+ can't be opened (e.g. because it doesn't exists, or there's a
+ permissions problem), an error is signaled.
+
+ SOURCE NOTE: this is enumerated in the Kernel report but the text
+ is still missing.
+
+ -- Applicative: open-output-file (open-output-file string)
+ `string' should be the name/path for an existing file.
+
+ Applicative `open-output-file' creates and returns an output port
+ associated with the file represented with `string'. If the file
+ can't be opened (e.g. if there's a permissions problem), an error
+ is signaled.
+
+ In klisp, for now, applicative `open-output-file' truncates the
+ file if it already exists, but that could change later (i.e. like
+ in scheme the behaviour should be considered unspecified).
+
+ SOURCE NOTE: this is enumerated in the Kernel report but the text
+ is still missing.
+
+ -- close-input-file: (close-input-file input-port)
+ -- close-output-file: (close-output-file output-port)
+ These applicatives close the port argument, so that no more
+ input/output may be performed on them, and the resources can be
+ freed. If the port was already closed these applicatives have no
+ effect.
+
+ The result returned by applicatives `close-input-file' and
+ `close-output-file' is inert.
+
+ SOURCE NOTE: this is enumerated in the Kernel report but the text
+ is still missing. There's probably a name error here. These
+ should probably be called close-input-port & close-output-port.
+
+ -- Applicative: read (read [input-port])
+ If the `port' optional argument is not specified, then the value
+ of the `input-port' keyed dynamic variable is used. If the port
+ is closed, an error is signaled.
+
+ Applicative `read' reads & returns the next parseable object from
+ the given port, or the eof object if no objects remain. If `read'
+ finds and unparseable object in the port, an error is signaled.
+ In that case, the remaining position in the port is unspecified.
+
+ SOURCE NOTE: this is enumerated in the Kernel report but the text
+ is still missing.
+
+ -- write: (write object [port])
+ If the `port' optional argument is not specified, then the value
+ of the `output-port' keyed dynamic variable is used. If the port
+ is closed, an error is signaled.
+
+ Applicative `write' writes an external representation of `object'
+ to the specified port. This may be an output-only representation
+ that can't be read by applicative `read' in cases where the type
+ of `object' doen't have a parseable external representation (e.g.
+ combiners and environments). The result returned by `write' is
+ inert.
+
+ SOURCE NOTE: this is enumerated in the Kernel report but the text
+ is still missing.
+
+ -- Applicative: call-with-input-file (call-with-input-file string
+ combiner)
+ -- Applicative: call-with-output-file (call-with-output-file string
+ combiner)
+ These applicatives open file named in `string' and call their
+ `combiner' argument in a fresh empty environment passing it as a
+ sole operand the opened port. When/if the combiner normally
+ returns a value the port is closed and that value is returned as
+ the result of the applicative.
+
+ SOURCE NOTE: this is enumerated in the Kernel report but the text
+ is still missing.
+
+ -- Applicative: load (load string)
+ Applicative `load' opens for input a file named `string'; reads
+ objects from the file until the end of the file is reached;
+ evaluates those objects consecutively in the created environment.
+ The result from applicative `load' is inert.
+
+ SOURCE NOTE: load is enumerated in the Kernel report, but the
+ description is not there yet. This seems like a sane way to define
+ it, taking the description of `get-module' that there is in the
+ report. The one detail that I think is still open, is whether to
+ return `#inert' (as is the case with klisp currently) or rather
+ return the value of the last evaluation.
+
+ -- Applicative: get-module (get-module string [environment])
+ Applicative `get-module' creates a fresh standard environment;
+ opens for input a file named `string'; reads objects from the file
+ until the end of the file is reached; evaluates those objects
+ consecutively in the created environment; and, lastly, returns the
+ created environment. If the optional argument `environment' is
+ specified, the freshly created standard environment is augmented,
+ prior to evaluating read expressions, by binding symbol
+ `module-parameters' to the `environment' argument.
+
+ -- Applicative: eof-object? (eof-object? . objects)
+ The primitive type predicate for type eof. `eof-object?' returns
+ true iff all the objects in `objects' are of type eof.
+
+ SOURCE NOTE: This is not in the report, the idea is from Scheme.
+ The `eof-object?' name is also from scheme, but this will probably
+ be changed to just `eof?', for consistency with the other
+ primitive type predicates.
+
+ -- read-char: (read-char [port])
+ If the `port' optional argument is not specified, then the value
+ of the `input-port' keyed dynamic variable is used. If the port
+ is closed, an error is signaled.
+
+ Applicative `read-char' reads and returns a character (not an
+ external representation of a character) from the specified port, or
+ an eof if the end of file was reached.
+
+ SOURCE NOTE: this is missing from Kernel, it is taken from Scheme.
+
+ -- peek-char: (peek-char [port])
+ If the `port' optional argument is not specified, then the value
+ of the `input-port' keyed dynamic variable is used. If the port
+ is closed, an error is signaled.
+
+ Applicative `peek-char' reads and returns a character (not an
+ external representation of a character) from the specified port, or
+ an eof if the end of file was reached. The position of the port
+ remains unchanged so that new call to `peek-char' or `read-char'
+ on the same port return the same character.
+
+ SOURCE NOTE: this is missing from Kernel, it is taken from Scheme.
+
+ -- char-ready?: (char-ready? [port])
+ If the `port' optional argument is not specified, then the value
+ of the `input-port' keyed dynamic variable is used. If the port
+ is closed, an error is signaled.
+
+ Predicate `char-ready?' checks to see if a character is available
+ in the specified port. If it returns true, then a `read-char' or
+ `peek-char' on that port is guaranteed not to block/hang. For now
+ in klisp this is hardcoded to `#t' because the code to do this is
+ non-portable.
+
+ SOURCE NOTE: this is missing from Kernel, it is taken from Scheme.
+
+ -- write-char: (write-char char [port])
+ If the `port' optional argument is not specified, then the value
+ of the `output-port' keyed dynamic variable is used. If the port
+ is closed, an error is signaled.
+
+ Applicative `write-char' writes the `char' character (not an
+ external representation of the character) to the specified port.
+ The result returned by `write-char' is inert.
+
+ SOURCE NOTE: this is missing from Kernel, it is taken from Scheme.
+
+ -- newline: (newline [port])
+ If the `port' optional argument is not specified, then the value
+ of the `output-port' keyed dynamic variable is used. If the port
+ is closed, an error is signaled.
+
+ Applicative `newline' writes a newline to the specified port. The
+ result returned by `newline' is inert.
+
+ SOURCE NOTE: this is missing from Kernel, it is taken from Scheme.
+
+ -- display: (display object [port])
+ If the `port' optional argument is not specified, then the value
+ of the `output-port' keyed dynamic variable is used. If the port
+ is closed, an error is signaled.
+
+ Applicative `display' behaves like `write' except that strings are
+ not enclosed in double quotes and no character is escaped within
+ those strings and character objects are output as if by
+ `write-char' instead of `read'. The result returned by `display'
+ is inert.
+
+ SOURCE NOTE: this is missing from Kernel, it is taken from Scheme.
+
File: klisp.info, Node: Index, Next: (dir), Prev: Ports, Up: Top
@@ -1612,7 +1851,8 @@ Index
* $sequence: Control. (line 23)
* $set!: Environments. (line 182)
* $vau: Combiners. (line 26)
-* ( <1>: Continuations. (line 143)
+* ( <1>: Ports. (line 37)
+* ( <2>: Continuations. (line 143)
* (: Environments. (line 174)
* and?: Booleans. (line 20)
* append: Pairs and lists. (line 208)
@@ -1641,6 +1881,8 @@ Index
* cadddr: Pairs and lists. (line 108)
* caddr: Pairs and lists. (line 96)
* cadr: Pairs and lists. (line 90)
+* call-with-input-file: Ports. (line 131)
+* call-with-output-file: Ports. (line 133)
* call/cc: Continuations. (line 43)
* car: Pairs and lists. (line 85)
* cdaaar: Pairs and lists. (line 109)
@@ -1677,6 +1919,7 @@ Index
* encycle!: Pairs and lists. (line 158)
* environment?: Environments. (line 23)
* environments: Environments. (line 6)
+* eof-object?: Ports. (line 166)
* eq?: Equivalence. (line 12)
* equal?: Equivalence. (line 16)
* equivalence: Equivalence. (line 6)
@@ -1695,12 +1938,14 @@ Index
* force: Promises. (line 35)
* get-current-environment: Environments. (line 114)
* get-list-metrics: Pairs and lists. (line 123)
+* get-module: Ports. (line 156)
* guard-continuation: Continuations. (line 63)
* guard-dynamic-extent: Continuations. (line 156)
* ignore: Environments. (line 6)
* ignore?: Environments. (line 28)
* inert: Control. (line 6)
* inert?: Control. (line 11)
+* input-port?: Ports. (line 27)
* Kernel history: Kernel History. (line 6)
* keyed dynamic variables: Keyed Variables. (line 15)
* keyed static variables: Keyed Variables. (line 40)
@@ -1712,6 +1957,7 @@ Index
* list-ref: Pairs and lists. (line 198)
* list-tail: Pairs and lists. (line 147)
* lists: Pairs and lists. (line 6)
+* load: Ports. (line 143)
* make-encapsulation-type: Encapsulations. (line 12)
* make-environment: Environments. (line 36)
* make-kernel-standard-environment: Environments. (line 119)
@@ -1728,17 +1974,22 @@ Index
* numbers: Numbers. (line 6)
* object descriptions: A Sample Applicative Description.
(line 6)
+* open-input-file: Ports. (line 62)
+* open-output-file: Ports. (line 73)
* operative descriptions: A Sample Applicative Description.
(line 6)
* operative?: Combiners. (line 16)
* operatives: Combiners. (line 6)
* or?: Booleans. (line 24)
+* output-port?: Ports. (line 28)
* pair?: Pairs and lists. (line 27)
* pairs: Pairs and lists. (line 6)
+* port?: Ports. (line 23)
* ports: Ports. (line 6)
* printing notation: Printing Notation. (line 6)
* promise?: Promises. (line 31)
* promises: Promises. (line 6)
+* read: Ports. (line 102)
* reduce: Pairs and lists. (line 270)
* root-continuation: Continuations. (line 104)
* set-car!: Pairs and lists. (line 41)
@@ -1782,6 +2033,6 @@ Node: Numbers72131
Node: Strings72240
Node: Characters72344
Node: Ports72452
-Node: Index72548
+Node: Index83737
End Tag Table
diff --git a/manual/src/ports.texi b/manual/src/ports.texi
@@ -6,3 +6,267 @@
@chapter Ports
@cindex ports
+
+ A port is an object that mediates character-based input from a
+source or character-based output to a destination. In the former case,
+the port is an input port, in the latter case, an output port.
+
+@c TODO add xref to equal? & eq?
+ Although ports are not considered immutable, none of the operations
+on ports described in this section constitute mutation. Ports are
+@code{equal?} iff @code{eq?}. The port type is encapsulated.
+
+ An auxiliary data type used to signal the end of file was reached is
+eof. The eof type consists of a single immutable value, having
+an output only external representation (so that it can never be the
+normal result of a call to read). The eof type is encapsulated.
+
+SOURCE NOTE: the eof type is not in the Kernel report, it is used in
+klisp and was taken from Scheme.
+
+@deffn Applicative port? (port? . objects)
+ The primitive type predicate for type port. @code{port?}
+returns true iff all the objects in @code{objects} are of type port.
+@end deffn
+
+@deffn Applicative input-port? (input-port? . objects)
+@deffnx Applicative output-port? (output-port? . objects)
+ Applicative @code{input-port?} is a predicate that returns true
+unless one or more of its arguments is not an input port. Applicative
+output-port? is a predicate that returns true unless one or more of
+its arguments is not an output port.
+
+ Every port must be admitted by at least one of these two predicates.
+@end deffn
+
+@deffn with-input-from-file (with-input-from-file string combiner)
+@deffnx with-output-to-file (with-output-to-file string combiner)
+@c add xref get-current-input-port/get-current-output-port
+ These two applicatives open the file named in @code{string} for
+input or output, an invoke the binder of the input-port & output-port
+keyed dynamic variables respectively with the opened port & the passed
+@code{combiner} (this means that the combiner is called in a fresh, empty
+dynamic environment). When/if the binder normally returns, the port is closed.
+The result of the applicatives @code{with-input-from-file} and
+@code{with-output-from-file} is inert.
+
+ SOURCE NOTE: this is enumerated in the Kernel report but the text is
+still missing. In the new scheme report there's also a third
+error-port variable. It is very likely that that will be added to the
+klisp implementation in the near future.
+@end deffn
+
+@deffn get-current-input-port (get-current-input-port)
+@deffnx get-current-output-port (get-current-output-port)
+ These are the accessors for the input-port and output-port keyed
+dynamic variables repectively.
+@c add xref to with-input-from-file, etc
+@c add xref and text for these dynamic vars
+
+ SOURCE NOTE: this is enumerated in the Kernel report but the text is
+still missing. In the new scheme report there's also a third
+error-port variable. It is very likely that that will be added to the
+klisp implementation in the near future.
+@end deffn
+
+@deffn Applicative open-input-file (open-input-file string)
+ @code{string} should be the name/path for an existing file.
+
+ Applicative @code{open-input-file} creates and returns an input port
+associated with the file represented with @code{string}. If the file
+can't be opened (e.g. because it doesn't exists, or there's a
+permissions problem), an error is signaled.
+
+ SOURCE NOTE: this is enumerated in the Kernel report but the text is
+still missing.
+@end deffn
+
+@deffn Applicative open-output-file (open-output-file string)
+ @code{string} should be the name/path for an existing file.
+
+ Applicative @code{open-output-file} creates and returns an output
+port associated with the file represented with @code{string}. If the
+file can't be opened (e.g. if there's a permissions problem), an error
+is signaled.
+
+ In klisp, for now, applicative @code{open-output-file} truncates the
+file if it already exists, but that could change later (i.e. like in
+scheme the behaviour should be considered unspecified).
+
+ SOURCE NOTE: this is enumerated in the Kernel report but the text is
+still missing.
+@end deffn
+
+@deffn close-input-file (close-input-file input-port)
+@deffnx close-output-file (close-output-file output-port)
+ These applicatives close the port argument, so that no more
+input/output may be performed on them, and the resources can be
+freed. If the port was already closed these applicatives have no
+effect.
+
+ The result returned by applicatives @code{close-input-file} and
+@code{close-output-file} is inert.
+
+ SOURCE NOTE: this is enumerated in the Kernel report but the text is
+still missing. There's probably a name error here. These should
+probably be called close-input-port & close-output-port.
+@end deffn
+
+@deffn Applicative read (read [input-port])
+ If the @code{port} optional argument is not specified, then the
+value of the @code{input-port} keyed dynamic variable is used. If the
+port is closed, an error is signaled.
+
+ Applicative @code{read} reads & returns the next parseable object
+from the given port, or the eof object if no objects remain. If
+@code{read} finds and unparseable object in the port, an error is
+signaled. In that case, the remaining position in the port is
+unspecified.
+
+ SOURCE NOTE: this is enumerated in the Kernel report but the text is
+still missing.
+@end deffn
+
+@deffn write (write object [port])
+ If the @code{port} optional argument is not specified, then the
+value of the @code{output-port} keyed dynamic variable is used. If the
+port is closed, an error is signaled.
+
+@c TODO add xref to external representation
+ Applicative @code{write} writes an external representation of
+@code{object} to the specified port. This may be an output-only
+representation that can't be read by applicative @code{read} in cases
+where the type of @code{object} doen't have a parseable external
+representation (e.g. combiners and environments). The result returned
+by @code{write} is inert.
+
+
+ SOURCE NOTE: this is enumerated in the Kernel report but the text is
+still missing.
+@end deffn
+
+@deffn Applicative call-with-input-file (call-with-input-file string combiner)
+@deffnx Applicative call-with-output-file (call-with-output-file string combiner)
+ These applicatives open file named in @code{string} and call their
+@code{combiner} argument in a fresh empty environment passing it as a
+sole operand the opened port. When/if the combiner normally returns a
+value the port is closed and that value is returned as the result of
+the applicative.
+
+ SOURCE NOTE: this is enumerated in the Kernel report but the text is
+still missing.
+@end deffn
+
+@deffn Applicative load (load string)
+@c TODO add xref, open/input, read
+ Applicative @code{load} opens for input a file named @code{string};
+reads objects from the file until the end of the file is reached;
+evaluates those objects consecutively in the created environment. The
+result from applicative @code{load} is inert.
+
+ SOURCE NOTE: load is enumerated in the Kernel report, but the
+description is not there yet. This seems like a sane way to define
+it, taking the description of @code{get-module} that there is in the
+report. The one detail that I think is still open, is whether to
+return @code{#inert} (as is the case with klisp currently) or rather
+return the value of the last evaluation.
+@end deffn
+
+@deffn Applicative get-module (get-module string [environment])
+@c TODO add xref standard-environment, open/input, read
+ Applicative @code{get-module} creates a fresh standard environment;
+opens for input a file named @code{string}; reads objects from the
+file until the end of the file is reached; evaluates those objects
+consecutively in the created environment; and, lastly, returns the
+created environment. If the optional argument @code{environment} is
+specified, the freshly created standard environment is augmented,
+prior to evaluating read expressions, by binding symbol
+@code{module-parameters} to the @code{environment} argument.
+@end deffn
+
+@deffn Applicative eof-object? (eof-object? . objects)
+ The primitive type predicate for type eof. @code{eof-object?}
+returns true iff all the objects in @code{objects} are of type eof.
+
+ SOURCE NOTE: This is not in the report, the idea is from Scheme.
+The @code{eof-object?} name is also from scheme, but this will
+probably be changed to just @code{eof?}, for consistency with the other
+primitive type predicates.
+@end deffn
+
+@deffn read-char (read-char [port])
+ If the @code{port} optional argument is not specified, then the
+value of the @code{input-port} keyed dynamic variable is used. If the
+port is closed, an error is signaled.
+
+ Applicative @code{read-char} reads and returns a character (not
+an external representation of a character) from the specified port, or
+an eof if the end of file was reached.
+
+ SOURCE NOTE: this is missing from Kernel, it is taken from Scheme.
+@end deffn
+
+@deffn peek-char (peek-char [port])
+ If the @code{port} optional argument is not specified, then the
+value of the @code{input-port} keyed dynamic variable is used. If the
+port is closed, an error is signaled.
+
+ Applicative @code{peek-char} reads and returns a character (not
+an external representation of a character) from the specified port, or
+an eof if the end of file was reached. The position of the port
+remains unchanged so that new call to @code{peek-char} or
+@code{read-char} on the same port return the same character.
+
+ SOURCE NOTE: this is missing from Kernel, it is taken from Scheme.
+@end deffn
+
+@deffn char-ready? (char-ready? [port])
+ If the @code{port} optional argument is not specified, then the
+value of the @code{input-port} keyed dynamic variable is used. If the
+port is closed, an error is signaled.
+
+ Predicate @code{char-ready?} checks to see if a character is
+available in the specified port. If it returns true, then a
+@code{read-char} or @code{peek-char} on that port is guaranteed not to
+block/hang. For now in klisp this is hardcoded to @code{#t} because
+the code to do this is non-portable.
+
+ SOURCE NOTE: this is missing from Kernel, it is taken from Scheme.
+@end deffn
+
+@deffn write-char (write-char char [port])
+ If the @code{port} optional argument is not specified, then the
+value of the @code{output-port} keyed dynamic variable is used. If the
+port is closed, an error is signaled.
+
+ Applicative @code{write-char} writes the @code{char} character (not
+an external representation of the character) to the specified port.
+The result returned by @code{write-char} is inert.
+
+ SOURCE NOTE: this is missing from Kernel, it is taken from Scheme.
+@end deffn
+
+@deffn newline (newline [port])
+ If the @code{port} optional argument is not specified, then the
+value of the @code{output-port} keyed dynamic variable is used. If the
+port is closed, an error is signaled.
+
+ Applicative @code{newline} writes a newline to the specified port.
+The result returned by @code{newline} is inert.
+
+ SOURCE NOTE: this is missing from Kernel, it is taken from Scheme.
+@end deffn
+
+@deffn display (display object [port])
+ If the @code{port} optional argument is not specified, then the
+value of the @code{output-port} keyed dynamic variable is used. If the
+port is closed, an error is signaled.
+
+ Applicative @code{display} behaves like @code{write} except that
+strings are not enclosed in double quotes and no character is escaped
+within those strings and character objects are output as if by
+@code{write-char} instead of @code{read}. The result returned by
+@code{display} is inert.
+
+ SOURCE NOTE: this is missing from Kernel, it is taken from Scheme.
+@end deffn
diff --git a/src/kport.c b/src/kport.c
@@ -15,7 +15,7 @@
#include "kstring.h"
#include "kgc.h"
-/* XXX: per the c spec, this truncates the file if it extists! */
+/* XXX: per the c spec, this truncates the file if it exists! */
/* Ask John: what would be best? Probably should also include delete,
file-exists? and a mechanism to truncate or append to a file, or
throw error if it exists.