klisp

an open source interpreter for the Kernel Programming Language.
git clone http://git.hanabi.in/repos/klisp.git
Log | Files | Refs | README

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:
Mmanual/html/Index.html | 12++++++++++++
Mmanual/html/Ports.html | 283++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
Mmanual/klisp.info | 255++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
Mmanual/src/ports.texi | 264+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/kport.c | 2+-
5 files changed, 812 insertions(+), 4 deletions(-)

diff --git a/manual/html/Index.html b/manual/html/Index.html @@ -55,6 +55,7 @@ Up:&nbsp;<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:&nbsp;<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:&nbsp;<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:&nbsp;<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:&nbsp;<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:&nbsp;<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:&nbsp;<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"> +&mdash; 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"> +&mdash; Applicative: <b>input-port?</b> (<var>input-port? . objects</var>)<var><a name="index-input_002dport_003f-155"></a></var><br> +&mdash; 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"> +&mdash; 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> +&mdash; 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 &amp; output-port +keyed dynamic variables respectively with the opened port &amp; 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"> +&mdash; get-current-input-port: <b>(</b><var>get-current-input-port</var>)<var><a name="index-g_t_0028-159"></a></var><br> +&mdash; 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"> +&mdash; 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"> +&mdash; 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"> +&mdash; close-input-file: <b>(</b><var>close-input-file input-port</var>)<var><a name="index-g_t_0028-163"></a></var><br> +&mdash; 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 &amp; close-output-port. +</p></blockquote></div> + +<div class="defun"> +&mdash; 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 &amp; 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"> +&mdash; 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"> +&mdash; 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> +&mdash; 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"> +&mdash; 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"> +&mdash; 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"> +&mdash; 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"> +&mdash; 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"> +&mdash; 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"> +&mdash; 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"> +&mdash; 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"> +&mdash; 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"> +&mdash; 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.