klisp

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

ports.texi (23938B)


      1 @c -*-texinfo-*-
      2 @setfilename ../src/ports
      3 
      4 @node Ports, Vectors, Characters, Top
      5 @comment  node-name,  next,  previous,  up
      6 
      7 @chapter Ports
      8 @cindex ports
      9 
     10 A port is an object that mediates data from an input or to a
     11 destination.  In the former case, the port is an input port, in the
     12 latter case, an output port.  The data itself can consist of either
     13 characters or bytes.  In the former case the port is a textual port
     14 and in the latter case, a binary port.
     15 
     16 There are three textual ports open, binded by dynamic variables, one
     17 for standard input, output, and error.
     18 
     19 @c TODO add xref to equal? & eq?
     20 Although ports are not considered immutable, none of the operations on
     21 ports described in this section constitute mutation.  Ports are
     22 @code{equal?} iff @code{eq?}.  The port type is encapsulated.
     23 
     24 An auxiliary data type used to signal the end of file was reached is
     25 @code{eof}. The eof type consists of a single immutable value, having
     26 an output only external representation (so that it can never be the
     27 normal result of a call to read).  The eof type is encapsulated.
     28 
     29 SOURCE NOTE:  the eof type is not in the Kernel report, it is used in
     30 klisp and was taken from r7rs.
     31 
     32 @deffn Applicative port? (port? . objects)
     33 The primitive type predicate for type port.  @code{port?}  returns
     34 true iff all the objects in @code{objects} are of type port.
     35 @end deffn
     36 
     37 @deffn Applicative input-port? (input-port? . objects)
     38 @deffnx Applicative output-port? (output-port? . objects)
     39 Applicative @code{input-port?} is a predicate that returns true unless
     40 one or more of its arguments is not an input port.  Applicative
     41 @code{output-port?} is a predicate that returns true unless one or
     42 more of its arguments is not an output port.
     43 
     44 Every port must be admitted by at least one of these two predicates.
     45 @end deffn
     46 
     47 @deffn Applicative textual-port? (textual-port? . objects)
     48 @deffnx Applicative binary-port? (binary-port? . objects)
     49 Applicative @code{textual-port?} is a predicate that returns true
     50 unless one or more of its arguments is not a textual port.
     51 Applicative @code{binary-port?} is a predicate that returns true
     52 unless one or more of its arguments is not a binary port.
     53 
     54 Every port must be admitted by at least one of these two predicates.
     55 
     56 SOURCE NOTE: this is missing from Kernel, it is taken from r7rs.
     57 @end deffn
     58 
     59 @deffn Applicative file-port? (file-port? . objects)
     60 @deffnx Applicative string-port? (string-port? . objects)
     61 @deffnx Applicative bytevector-port? (bytevector-port? . objects)
     62 These applictives are predicates that returns true unless one or more
     63 of its arguments is not a file, string or bytevector port,
     64 repectively.
     65 
     66 Every port in klisp is be admitted by exactly one of these predicates.
     67 
     68 SOURCE NOTE: this is missing from Kernel, but convenient in the face
     69 of the different port types admited by klisp.
     70 @end deffn
     71 
     72 @deffn Applicative port-open? (port-open? port)
     73 Applicative @code{port-open?} returns true iff @code{port} is still
     74 open.
     75 
     76 SOURCE NOTE: this is taken from r7rs.
     77 @end deffn
     78 
     79 @deffn Applicative with-input-from-file (with-input-from-file string combiner)
     80 @deffnx Applicative with-output-to-file (with-output-to-file string combiner)
     81 @deffnx Applicative with-error-to-file (with-error-to-file string combiner)
     82 @c add xref get-current-input-port/get-current-output-port
     83 These three applicatives open the file named in @code{string} for
     84 textual input or output, an invoke the binder of either the
     85 input-port, the output-port or the error-port keyed dynamic variables
     86 respectively with the opened port & the passed @code{combiner} (this
     87 means that the combiner is called in a fresh, empty dynamic
     88 environment).  When/if the binder normally returns, the port is
     89 closed.  The result of the applicatives @code{with-input-from-file}
     90 and @code{with-output-from-file} is inert.
     91 
     92 SOURCE NOTE: The first two are enumerated in the Kernel report but
     93 the text is still missing.  The third applicative is from r7rs.
     94 @end deffn
     95 
     96 @deffn Applicative get-current-input-port (get-current-input-port)
     97 @deffnx Applicative get-current-output-port (get-current-output-port)
     98 @deffnx Applicative get-current-error-port (get-current-error-port)
     99 These are the accessors for the input-port, output-port, and
    100 error-port keyed dynamic variables repectively.
    101 @c add xref to with-input-from-file, etc
    102 @c add xref and text for these dynamic vars
    103 
    104 SOURCE NOTE: The first two are enumerated in the Kernel report but the
    105 text is still missing.  The third applicative is from r7rs.
    106 @end deffn
    107 
    108 @deffn Applicative open-input-file (open-input-file string)
    109 @deffnx Applicative open-binary-input-file (open-binary-input-file string)
    110 @code{string} should be the name/path for an existing file.
    111 
    112 Applicative @code{open-input-file} creates and returns a textual input
    113 port associated with the file represented with @code{string}.
    114 Applicative @code{open-binary-input-file} creates and returns a binary
    115 input port associated with the file represented with @code{string}.
    116 In either case, if the file can't be opened (e.g. because it doesn't
    117 exists, or there's a permissions problem), an error is signaled.
    118 
    119 SOURCE NOTE: @code{open-input-file} is enumerated in the Kernel report
    120 but the text is still missing. @code{open-binary-input-file} is from
    121 r7rs.
    122 @end deffn
    123 
    124 @deffn Applicative open-output-file (open-output-file string)
    125 @deffnx Applicative open-binary-output-file (open-binary-output-file string)
    126 @code{string} should be the name/path for an existing file.
    127 
    128 Applicative @code{open-output-file} creates and returns a textual
    129 output port associated with the file represented with @code{string}.
    130 Applicative @code{open-binary-output-file} creates and returns a
    131 binary output port associated with the file represented with
    132 @code{string}.  In either case, if the file can't be opened (e.g. if
    133 there's a permissions problem), an error is signaled.
    134 
    135 In klisp, for now, applicative @code{open-output-file} and
    136 @code{open-binary-output-file} truncate the file if it already exists,
    137 but that could change later (i.e. like in Scheme the behaviour should
    138 be considered unspecified).
    139 
    140 SOURCE NOTE: @code{open-output-file} is enumerated in the Kernel
    141 report but the text is still missing. @code{open-binary-output-file}
    142 is from r7rs.
    143 @end deffn
    144 
    145 @deffn Applicative open-input-string (open-output-string string)
    146 @deffnx Applicative open-input-bytevector (open-output-bytevector bytevector)
    147 These applicative return a fresh input port that reads characters or
    148 unsigned bytes from the passed sequence.
    149 
    150 SOURCE NOTE: These are taken from r7rs.
    151 @end deffn
    152 
    153 @deffn Applicative open-output-string (open-output-string)
    154 Applicative @code{open-output-string} returns a fresh textual
    155 output port that accumulates characters.  The accumulated data can
    156 @c TODO add xref
    157 be obtained via applicative @code{get-output-string}.
    158 
    159 SOURCE NOTE: This is taken from r7rs.
    160 @end deffn
    161 
    162 @deffn Applicative open-output-bytevector (open-output-bytevector)
    163 Applicative @code{open-output-bytevector} returns a fresh binary
    164 output port that accumulates unsigned bytes.  The accumulated data can
    165 @c TODO add xref
    166 be obtained via applicative @code{get-output-bytevector}.
    167 
    168 SOURCE NOTE: This is taken from r7rs.
    169 @end deffn
    170 
    171 @deffn Applicative close-input-file (close-input-file input-port)
    172 @deffnx Applicative close-output-file (close-output-file output-port)
    173 These applicatives close the port argument, so that no more
    174 input/output may be performed on them, and the resources can be freed.
    175 If the port was already closed these applicatives have no effect.
    176 
    177 The result returned by applicatives @code{close-input-file} and
    178 @code{close-output-file} is inert.
    179 
    180 SOURCE NOTE: this is enumerated in the Kernel report but the text is
    181 still missing.  There's probably a name error here.  These should
    182 probably be called close-input-port & close-output-port.
    183 @end deffn
    184 
    185 @deffn Applicative close-input-port (close-input-port input-port)
    186 @deffnx Applicative close-output-port (close-output-port output-port)
    187 @deffnx Applicative close-port (close-port port)
    188 These applicatives close the port argument, so that no more
    189 input/output may be performed on them, and the resources can be freed.
    190 If the port was already closed these applicatives have no effect.  If
    191 at some time klisp provided input/output ports these could be used to
    192 selectively close only one direction of the port.
    193 
    194 The result returned by applicatives @code{close-input-port},
    195 @code{close-output-port}, and @code{close-port} is inert.
    196 
    197 SOURCE NOTE: this is from r7rs. The equivalent @code{close-input-file}
    198 and @code{close-output-file} are probably name errors and only
    199 retained here till the draft standard rectifies them.
    200 @end deffn
    201 
    202 @deffn Applicative get-output-string (get-output-string port)
    203 @code{port} should be a string output port.
    204 
    205 Applicative @code{get-output-string} returns a freshly created mutable
    206 string representing the characters accumulated in @code{port} so far.
    207 @code{port} can be either open or closed.
    208 
    209 SOURCE NOTE: This is taken from r7rs.
    210 @end deffn
    211 
    212 @deffn Applicative get-output-bytevector (get-output-bytevector port)
    213 @code{port} should be a bytevector output port.
    214 
    215 Applicative @code{get-output-bytevector} returns a freshly created mutable
    216 bytevector representing the unsigned bytes accumulated in @code{port}
    217 so far.
    218 @code{port} can be either open or closed.
    219 
    220 SOURCE NOTE: This is taken from r7rs.
    221 @end deffn
    222 
    223 @deffn Applicative read (read [port])
    224 If the @code{port} optional argument is not specified, then the value
    225 of the @code{input-port} keyed dynamic variable is used.  If the port
    226 is closed, an error is signaled.  The port should be a textual input
    227 port.
    228 
    229 Applicative @code{read} reads & returns the next parseable object from
    230 the given port, or the @code{eof} if no objects remain.  If
    231 @code{read} finds and unparseable object in the port, an error is
    232 signaled.  In that case, the remaining position in the port is
    233 unspecified.
    234 
    235 SOURCE NOTE: this is enumerated in the Kernel report but the text is
    236 still missing.
    237 @end deffn
    238 
    239 @deffn Applicative write (write object [port])
    240 If the @code{port} optional argument is not specified, then the value
    241 of the @code{output-port} keyed dynamic variable is used.  If the port
    242 is closed, an error is signaled.  The port should be a textual output
    243 port.
    244 
    245 @c TODO add xref to external representation
    246 Applicative @code{write} writes an external representation of
    247 @code{object} to the specified port.  This may be an output-only
    248 representation that can't be read by applicative @code{read} in cases
    249 where the type of @code{object} doen't have a parseable external
    250 representation (e.g. combiners and environments).  The result returned
    251 by @code{write} is inert.  @code{write} is guaranteed to terminate
    252 even in the case of objects with shared or cyclic structure.  In those
    253 cases @code{write} will use special syntax to preserve sharing info.
    254 @c TODO add section and xref on sharing external representation
    255 
    256   SOURCE NOTE: this is enumerated in the Kernel report but the text is
    257 still missing.
    258 @end deffn
    259 
    260 @deffn Applicative write-simple (write-simple object [port])
    261 Applicative @code{write-simple} is like @code{write} except that it
    262 doesn't write sharing info. It will hang if handed a cyclic structure.
    263 
    264 SOURCE NOTE: this is taken from r7rs.
    265 @end deffn
    266 
    267 @deffn Applicative eof-object? (eof-object? . objects)
    268 The primitive type predicate for type eof.  @code{eof-object?}
    269 returns true iff all the objects in @code{objects} are of type eof.
    270 
    271 SOURCE NOTE: This is not in the report, the idea is from Scheme.  The
    272 @code{eof-object?} name is also from Scheme, but this will probably be
    273 changed to just @code{eof?}, for consistency with the other primitive
    274 type predicates.
    275 @end deffn
    276 
    277 @deffn Applicative newline (newline [port])
    278 If the @code{port} optional argument is not specified, then the value
    279 of the @code{output-port} keyed dynamic variable is used.  If the port
    280 is closed, an error is signaled.  The port should be a textual output
    281 port.
    282 
    283 Applicative @code{newline} writes a newline to the specified port.
    284 The result returned by @code{newline} is inert.
    285 
    286 SOURCE NOTE: this is missing from Kernel, it is taken from Scheme.
    287 @end deffn
    288 
    289 
    290 @deffn Applicative display (display object [port])
    291 If the @code{port} optional argument is not specified, then the value
    292 of the @code{output-port} keyed dynamic variable is used.  If the port
    293 is not a textual output port, or is closed, an error is signaled.
    294 
    295 Applicative @code{display} behaves like @code{write} except that
    296 strings are not enclosed in double quotes and no character is escaped
    297 within those strings and character objects are output as if by
    298 @code{write-char} instead of @code{write}. The result returned by
    299 @code{display} is inert.
    300 
    301 SOURCE NOTE: this is missing from Kernel, it is taken from Scheme.
    302 @end deffn
    303 
    304 @deffn Applicative read-line (read-line [port])
    305 If the @code{port} optional argument is not specified, then the value
    306 of the @code{input-port} keyed dynamic variable is used.  If the port
    307 is closed or if it is not a textual input port, an error is signaled.
    308 
    309 Applicative @code{read-line}
    310 
    311 SOURCE NOTE: this is taken from r7rs.
    312 @end deffn
    313 
    314 @deffn Applicative flush-output-port (flush-output-port [port])
    315 If the @code{port} optional argument is not specified, then the value
    316 of the @code{output-port} keyed dynamic variable is used.  If the port
    317 is closed or if it is not an output port, an error is signaled.
    318 
    319 Applicative @code{flush-output-port} flushes any buffered data in the
    320 output port to the underlying object (file, socket, pipe, memory
    321 sector, device, etc).  The result returned by @code{flush-output-port}
    322 is inert.
    323 
    324 SOURCE NOTE: this is missing from Kernel, it is taken from r7rs.
    325 @end deffn
    326 
    327 
    328 @deffn Applicative write-char (write-char char [port])
    329 If the @code{port} optional argument is not specified, then the
    330 value of the @code{output-port} keyed dynamic variable is used.  If the
    331 port is closed, an error is signaled.  The port should be a textual
    332 output port.
    333 
    334 Applicative @code{write-char} writes the @code{char} character (not
    335 an external representation of the character) to the specified port.
    336 The result returned by @code{write-char} is inert.
    337 
    338 SOURCE NOTE: this is missing from Kernel, it is taken from Scheme.
    339 @end deffn
    340 
    341 
    342 @deffn Applicative read-char (read-char [port])
    343 If the @code{port} optional argument is not specified, then the value
    344 of the @code{input-port} keyed dynamic variable is used.  If the port
    345 is closed, an error is signaled.  The port should be a textual input
    346 port.
    347 
    348 Applicative @code{read-char} reads and returns a character (not an
    349 external representation of a character) from the specified port, or an
    350 @code{eof} if the end of file was reached.
    351 
    352 SOURCE NOTE: this is missing from Kernel, it is taken from Scheme.
    353 @end deffn
    354 
    355 @deffn Applicative peek-char (peek-char [port])
    356 If the @code{port} optional argument is not specified, then the value
    357 of the @code{input-port} keyed dynamic variable is used.  If the port
    358 is closed, an error is signaled.  The port should be a textual input
    359 port.
    360 
    361 Applicative @code{peek-char} reads and returns a character (not an
    362 external representation of a character) from the specified port, or an
    363 @code{eof} if the end of file was reached.  The position of the port
    364 remains unchanged so that new call to @code{peek-char} or
    365 @code{read-char} on the same port return the same character.
    366 
    367 SOURCE NOTE: this is missing from Kernel, it is taken from Scheme.
    368 @end deffn
    369 
    370 @deffn Applicative char-ready? (char-ready? [port])
    371 If the @code{port} optional argument is not specified, then the value
    372 of the @code{input-port} keyed dynamic variable is used.  If the port
    373 is closed, an error is signaled.  The port should be a textual input
    374 port.
    375 
    376 Predicate @code{char-ready?} checks to see if a character is available
    377 in the specified port.  If it returns true, then a @code{read-char} or
    378 @code{peek-char} on that port is guaranteed not to block/hang.  For
    379 now in klisp this is hardcoded to @code{#t} because the code to do
    380 this is non-portable.
    381 
    382 SOURCE NOTE: this is missing from Kernel, it is taken from Scheme.
    383 @end deffn
    384 
    385 
    386 @deffn Applicative write-u8 (write-u8 u8 [port])
    387 If the @code{port} optional argument is not specified, then the
    388 value of the @code{output-port} keyed dynamic variable is used.  If the
    389 port is closed, an error is signaled.  The port should be a binary
    390 output port.
    391 
    392 Applicative @code{write-u8} writes the byte represented by the
    393 unsigned integer @code{u8}, that should be between 0 and 255 inclusive,
    394 (not an external representation of byte) to the specified port.  The
    395 result returned by @code{write-u8} is inert.
    396 
    397 SOURCE NOTE: this is missing from Kernel, it is taken from r7rs.
    398 @end deffn
    399 
    400 @deffn Applicative read-u8 (read-u8 [port])
    401 If the @code{port} optional argument is not specified, then the value
    402 of the @code{input-port} keyed dynamic variable is used.  If the port
    403 is closed, an error is signaled.  The port should be a binary input
    404 port.
    405 
    406 Applicative @code{read-u8} reads and returns a byte as an exact
    407 unsigned integer between 0 and 255 inclusive (not an external
    408 representation of a byte) from the specified port, or an @code{eof} if
    409 the end of file was reached.
    410 
    411 SOURCE NOTE: this is missing from Kernel, it is taken from r7rs.
    412 @end deffn
    413 
    414 @deffn Applicative peek-u8 (peek-u8 [port])
    415 If the @code{port} optional argument is not specified, then the
    416 value of the @code{input-port} keyed dynamic variable is used.  If the
    417 port is closed, an error is signaled.  The port should be a binary
    418 input port.
    419 
    420 Applicative @code{peek-u8} reads and returns a byte as an exact
    421 unsigned integer between 0 and 255 inclusive (not an external
    422 representation of a byte) from the specified port, or an @code{eof} if
    423 the end of file was reached.  The position of the port remains
    424 unchanged so that new call to @code{peek-u8} or @code{read-u8} on the
    425 same port return the same byte.
    426 
    427 SOURCE NOTE: this is missing from Kernel, it is taken from r7rs.
    428 @end deffn
    429 
    430 @deffn Applicative u8-ready? (u8-ready? [port])
    431 If the @code{port} optional argument is not specified, then the
    432 value of the @code{input-port} keyed dynamic variable is used.  If the
    433 port is closed, an error is signaled.  The port should be a binary
    434 input port.
    435 
    436 Predicate @code{u8-ready?} checks to see if a byte is
    437 available in the specified port.  If it returns true, then a
    438 @code{read-u8} or @code{peek-u8} on that port is guaranteed not to
    439 block/hang.  For now in klisp this is hardcoded to @code{#t} because
    440 the code to do this is non-portable.
    441 
    442 SOURCE NOTE: this is missing from Kernel, it is taken from r7rs.
    443 @end deffn
    444 
    445 @deffn Applicative call-with-input-file (call-with-input-file string combiner)
    446 @deffnx Applicative call-with-output-file (call-with-output-file string combiner)
    447 These applicatives open file named in @code{string} for textual
    448 input/output respectively and call their @code{combiner} argument in a
    449 fresh empty environment passing it as a sole operand the opened port.
    450 When/if the combiner normally returns a value the port is closed and
    451 that value is returned as the result of the applicative.
    452 
    453 SOURCE NOTE: this is enumerated in the Kernel report but the text is
    454 still missing.
    455 @end deffn
    456 
    457 @deffn Applicative load (load string)
    458 @c TODO add xref, open/input, read
    459 Applicative @code{load} opens the file named @code{string} for textual
    460 input; reads immutable objects from the file until the end of the file
    461 is reached; evaluates those objects consecutively in the created
    462 environment.  The result from applicative @code{load} is inert.
    463 
    464 Notice that if @code{string} is a relative path it is looked in the
    465 current directory (whatever that means in your OS, normally the
    466 directory from which the interpreted was run or the directory where
    467 the interpreter executable lives).  klisp doesn't track the directory
    468 from which the current code was read, so there's in principle no way
    469 to load a file in the same directory as the currently executing code
    470 with a relative path.  See @code{find-required-filename} for a way to
    471 look for a file in a number of directories.
    472 
    473 SOURCE NOTE: load is enumerated in the Kernel report, but the
    474 description is not there yet.  This seems like a sane way to define
    475 it, taking the description of @code{get-module} that there is in the
    476 report.  The one detail that I think is still open, is whether to
    477 return @code{#inert} (as is the case with klisp currently) or rather
    478 return the value of the last evaluation.
    479 @end deffn
    480 
    481 @deffn Applicative require (require string)
    482 Applicative @code{require} looks for @code{string} following the
    483 algorithm described in applicative @code{find-required-filename}.  If
    484 an appropriate file can't be found, and error is signaled.  Otherwise,
    485 the file is opened for textual input; immutable objects are read and
    486 acumulated until the end of file is found; those objects are evaluated
    487 in a fresh standard environment; the results of evaluation are
    488 discarded and the result from applicative @code{require} is inert.
    489 
    490 Applicative @code{require} also register @code{string} (as via
    491 applicative @code{register-requirement!}) so that subsequent calls to
    492 @code{require} with exactly the same @code{string} will not cause any
    493 search or evaluation.  The mechanism used for this can also be
    494 manipulated directly by the programmer via applicatives
    495 @code{registered-requirement?}, @code{register-requirement!},
    496 @code{unregister-requirement!}, and @code{find-required-filename}.
    497 @c TODO add xref to fresh standard environment
    498 
    499 Applicative @code{require} is useful to load klisp libraries.
    500 
    501 SOURCE NOTE: require is taken from lua and r7rs.
    502 @end deffn
    503 
    504 @deffn Applicative registered-requirement? (registered-requirement? string)
    505 @deffnx Applicative register-requirement! (register-requirement! string)
    506 @deffnx Applicative unregister-requirement! (unregister-requirement! string)
    507 @deffnx Applicative find-required-filename (find-required-filename string)
    508 @code{string} should be non-empty.
    509 
    510 These applicatives control the underlying facilities used by
    511 @code{require} to register already required files.  Predicate
    512 @code{registered-requirement?} returns true iff @code{string} is
    513 already registered.  @code{register-requirement!} marks @code{string}
    514 as registered (throws an error if it was already registered).
    515 @code{unregister-requirement!} marks @code{string} as not being
    516 registered (throws an error if it wasn't registered).
    517 @code{find-required-filename} looks for an appropriate file for
    518 @code{string} using the algorithm described below.
    519 
    520 filename search in controlled by environment variable
    521 @code{KLISP_PATH}.  This environment variable should be a list of
    522 templates separated with semicolons (``;'').  Each template is a
    523 string that may contain embedded question mark characters (``?'') to
    524 be replaced with @code{string}.  After replacements, each template
    525 represents the path to a file.  All templates are probed in order, and
    526 the first to name an existing readable file is returned.  If no
    527 template corresponds to an existing readable file, an error is
    528 signaled.
    529 
    530 NOTE: in the future there will be some mechanism to alter the search
    531 algorithm dinamically, in the meantime this environment variable is
    532 the only way to customize it.
    533 
    534 SOURCE NOTE: this is not in Kernel, they are supplied per guideline
    535 G1b of the report (extensibility), so that klisp programs can easily
    536 duplicate the behaviour of @code{require}
    537 @end deffn
    538 
    539 @deffn Applicative get-module (get-module string [environment])
    540 @c TODO add xref standard-environment, open/input, read
    541 Applicative @code{get-module} creates a fresh standard environment;
    542 opens the file named @code{string} for textual input; reads objects
    543 from the file until the end of the file is reached; evaluates those
    544 objects consecutively in the created environment; and, lastly, returns
    545 the created environment.  If the optional argument @code{environment}
    546 is specified, the freshly created standard environment is augmented,
    547 prior to evaluating read expressions, by binding symbol
    548 @code{module-parameters} to the @code{environment} argument.
    549 @end deffn