From bd9733926076885e3417b74de76e4c9c7bc56254 Mon Sep 17 00:00:00 2001 From: Bryan Newbold Date: Mon, 20 Feb 2017 00:05:28 -0800 Subject: Import Upstream version 2c7 --- slib.info | 11240 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 11240 insertions(+) create mode 100644 slib.info (limited to 'slib.info') diff --git a/slib.info b/slib.info new file mode 100644 index 0000000..8e62273 --- /dev/null +++ b/slib.info @@ -0,0 +1,11240 @@ +This is Info file slib.info, produced by Makeinfo version 1.68 from the +input file slib.texi. + +INFO-DIR-SECTION The Algorithmic Language Scheme +START-INFO-DIR-ENTRY +* SLIB: (slib). Scheme Library +END-INFO-DIR-ENTRY + + This file documents SLIB, the portable Scheme library. + + Copyright (C) 1993 Todd R. Eigenschink +Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999 Aubrey Jaffer | + + Permission is granted to make and distribute verbatim copies of this +manual provided the copyright notice and this permission notice are +preserved on all copies. + + Permission is granted to copy and distribute modified versions of this +manual under the conditions for verbatim copying, provided that the +entire resulting derived work is distributed under the terms of a +permission notice identical to this one. + + Permission is granted to copy and distribute translations of this +manual into another language, under the above conditions for modified +versions, except that this permission notice may be stated in a +translation approved by the author. + + +File: slib.info, Node: Top, Next: The Library System, Prev: (dir), Up: (dir) + +"SLIB" is a portable library for the programming language "Scheme". It | +provides a platform independent framework for using "packages" of | +Scheme procedures and syntax. As distributed, SLIB contains useful +packages for all Scheme implementations. Its catalog can be | +transparently extended to accomodate packages specific to a site, | +implementation, user, or directory. | + +* Menu: + +* The Library System:: How to use and customize. +* Scheme Syntax Extension Packages:: +* Textual Conversion Packages:: +* Mathematical Packages:: +* Database Packages:: +* Other Packages:: +* About SLIB:: Install, etc. +* Index:: + + +File: slib.info, Node: The Library System, Next: Scheme Syntax Extension Packages, Prev: Top, Up: Top + +The Library System +****************** + +* Menu: + +* Feature:: SLIB names. +* Requesting Features:: +* Library Catalogs:: +* Catalog Compilation:: +* Built-in Support:: +* About this manual:: + + +File: slib.info, Node: Feature, Next: Requesting Features, Prev: The Library System, Up: The Library System + +Feature +======= + +SLIB denotes "features" by symbols. SLIB maintains a list of features +supported by the Scheme "session". The set of features provided by a +session may change over time. Some features are properties of the +Scheme implementation being used. The following features detail what +sort of numbers are available from an implementation. + + * 'inexact + + * 'rational + + * 'real + + * 'complex + + * 'bignum + +Other features correspond to the presence of sets of Scheme procedures +or syntax (macros). + + - Function: provided? FEATURE + Returns `#t' if FEATURE is supported by the current Scheme session. + + - Procedure: provide FEATURE + Informs SLIB that FEATURE is supported. Henceforth `(provided? + FEATURE)' will return `#t'. + + (provided? 'foo) => #f + (provide 'foo) + (provided? 'foo) => #t + + +File: slib.info, Node: Requesting Features, Next: Library Catalogs, Prev: Feature, Up: The Library System + +Requesting Features +=================== + +SLIB creates and maintains a "catalog" mapping features to locations of +files introducing procedures and syntax denoted by those features. + +At the beginning of each section of this manual, there is a line like +`(require 'FEATURE)'. The Scheme files comprising SLIB are cataloged +so that these feature names map to the corresponding files. + +SLIB provides a form, `require', which loads the files providing the +requested feature. + + - Procedure: require FEATURE + * If `(provided? FEATURE)' is true, then `require' just returns + an unspecified value. + + * Otherwise, if FEATURE is found in the catalog, then the + corresponding files will be loaded and an unspecified value + returned. + + Subsequently `(provided? FEATURE)' will return `#t'. + + * Otherwise (FEATURE not found in the catalog), an error is + signaled. + +The catalog can also be queried using `require:feature->path'. + + - Function: require:feature->path FEATURE + * If FEATURE is already provided, then returns `#t'. + + * Otherwise, if FEATURE is in the catalog, the path or list of + paths associated with FEATURE is returned. + + * Otherwise, returns `#f'. + + +File: slib.info, Node: Library Catalogs, Next: Catalog Compilation, Prev: Requesting Features, Up: The Library System + +Library Catalogs +================ + +At the start of a session no catalog is present, but is created with the +first catalog inquiry (such as `(require 'random)'). Several sources +of catalog information are combined to produce the catalog: + + * standard SLIB packages. + + * additional packages of interest to this site. + + * packages specifically for the variety of Scheme which this session + is running. + + * packages this user wants to always have available. This catalog + is the file `homecat' in the user's "HOME" directory. + + * packages germane to working in this (current working) directory. + This catalog is the file `usercat' in the directory to which it + applies. One would typically `cd' to this directory before + starting the Scheme session. + +Catalog files consist of one or more "association list"s. In the +circumstance where a feature symbol appears in more than one list, the +latter list's association is retrieved. Here are the supported formats +for elements of catalog lists: + +`(FEATURE . )' + Redirects to the feature named . + +`(FEATURE . "")' + Loads file . + +`(FEATURE source "")' + `slib:load's the Scheme source file . + +`(FEATURE compiled "" ...)' + `slib:load-compiled's the files .... + +The various macro styles first `require' the named macro package, then +just load or load-and-macro-expand as appropriate for the +implementation. + +`(FEATURE defmacro "")' + `defmacro:load's the Scheme source file . + +`(FEATURE macro-by-example "")' + `defmacro:load's the Scheme source file . + +`(FEATURE macro "")' + `macro:load's the Scheme source file . + +`(FEATURE macros-that-work "")' + `macro:load's the Scheme source file . + +`(FEATURE syntax-case "")' + `macro:load's the Scheme source file . + +`(FEATURE syntactic-closures "")' + `macro:load's the Scheme source file . + +Here is an example of a `usercat' catalog. A Program in this directory +can invoke the `run' feature with `(require 'run)'. + + ;;; "usercat": SLIB catalog additions for SIMSYNCH. -*-scheme-*- + + ( + (simsynch . "../synch/simsynch.scm") + (run . "../synch/run.scm") + (schlep . "schlep.scm") + ) + + +File: slib.info, Node: Catalog Compilation, Next: Built-in Support, Prev: Library Catalogs, Up: The Library System + +Catalog Compilation +=================== + +SLIB combines the catalog information which doesn't vary per user into +the file `slibcat' in the implementation-vicinity. Therefore `slibcat' +needs change only when new software is installed or compiled. Because +the actual pathnames of files can differ from installation to +installation, SLIB builds a separate catalog for each implementation it +is used with. + +The definition of `*SLIB-VERSION*' in SLIB file `require.scm' is +checked against the catalog association of `*SLIB-VERSION*' to +ascertain when versions have changed. I recommend that the definition +of `*SLIB-VERSION*' be changed whenever the library is changed. If +multiple implementations of Scheme use SLIB, remember that recompiling +one `slibcat' will fix only that implementation's catalog. + +The compilation scripts of Scheme implementations which work with SLIB +can automatically trigger catalog compilation by deleting `slibcat' or +by invoking a special form of `require': + + - Procedure: require 'new-catalog + This will load `mklibcat', which compiles and writes a new + `slibcat'. + +Another special form of `require' erases SLIB's catalog, forcing it to +be reloaded the next time the catalog is queried. + + - Procedure: require #f + Removes SLIB's catalog information. This should be done before + saving an executable image so that, when restored, its catalog + will be loaded afresh. + +Each file in the table below is descibed in terms of its file-system +independent "vicinity" (*note Vicinity::.). The entries of a catalog +in the table override those of catalogs above it in the table. + +`implementation-vicinity' `slibcat' + This file contains the associations for the packages comprising + SLIB, the `implcat' and the `sitecat's. The associations in the + other catalogs override those of the standard catalog. + +`library-vicinity' `mklibcat.scm' + creates `slibcat'. + +`library-vicinity' `sitecat' + This file contains the associations specific to an SLIB + installation. + +`implementation-vicinity' `implcat' + This file contains the associations specific to an implementation + of Scheme. Different implementations of Scheme should have + different `implementation-vicinity'. + +`implementation-vicinity' `mkimpcat.scm' + if present, creates `implcat'. + +`implementation-vicinity' `sitecat' + This file contains the associations specific to a Scheme + implementation installation. + +`home-vicinity' `homecat' + This file contains the associations specific to an SLIB user. + +`user-vicinity' `usercat' + This file contains associations effecting only those sessions whose + "working directory" is `user-vicinity'. + + +File: slib.info, Node: Built-in Support, Next: About this manual, Prev: Catalog Compilation, Up: The Library System + +Built-in Support +================ + +The procedures described in these sections are supported by all +implementations as part of the `*.init' files or by `require.scm'. + +* Menu: + +* Require:: Module Management +* Vicinity:: Pathname Management +* Configuration:: Characteristics of Scheme Implementation +* Input/Output:: Things not provided by the Scheme specs. +* Legacy:: +* System:: LOADing, EVALing, ERRORing, and EXITing + + +File: slib.info, Node: Require, Next: Vicinity, Prev: Built-in Support, Up: Built-in Support + +Require +------- + + - Variable: *features* + Is a list of symbols denoting features supported in this + implementation. *FEATURES* can grow as modules are `require'd. + *FEATURES* must be defined by all implementations (*note + Porting::.). + + Here are features which SLIB (`require.scm') adds to *FEATURES* + when appropriate. + + * 'inexact + + * 'rational + + * 'real + + * 'complex + + * 'bignum + + For each item, `(provided? 'FEATURE)' will return `#t' if that + feature is available, and `#f' if not. + + - Variable: *modules* + Is a list of pathnames denoting files which have been loaded. + + - Variable: *catalog* + Is an association list of features (symbols) and pathnames which + will supply those features. The pathname can be either a string + or a pair. If pathname is a pair then the first element should be + a macro feature symbol, `source', or `compiled'. The cdr of the + pathname should be either a string or a list. + +In the following functions if the argument FEATURE is not a symbol it +is assumed to be a pathname. + + - Function: provided? FEATURE + Returns `#t' if FEATURE is a member of `*features*' or `*modules*' + or if FEATURE is supported by a file already loaded and `#f' + otherwise. + + - Procedure: require FEATURE + FEATURE is a symbol. If `(provided? FEATURE)' is true `require' + returns. Otherwise, if `(assq FEATURE *catalog*)' is not `#f', + the associated files will be loaded and `(provided? FEATURE)' will + henceforth return `#t'. An unspecified value is returned. If + FEATURE is not found in `*catalog*', then an error is signaled. + + - Procedure: require PATHNAME + PATHNAME is a string. If PATHNAME has not already been given as + an argument to `require', PATHNAME is loaded. An unspecified + value is returned. + + - Procedure: provide FEATURE + Assures that FEATURE is contained in `*features*' if FEATURE is a + symbol and `*modules*' otherwise. + + - Function: require:feature->path FEATURE + Returns `#t' if FEATURE is a member of `*features*' or `*modules*' + or if FEATURE is supported by a file already loaded. Returns a + path if one was found in `*catalog*' under the feature name, and + `#f' otherwise. The path can either be a string suitable as an + argument to load or a pair as described above for *catalog*. + + +File: slib.info, Node: Vicinity, Next: Configuration, Prev: Require, Up: Built-in Support + +Vicinity +-------- + +A vicinity is a descriptor for a place in the file system. Vicinities +hide from the programmer the concepts of host, volume, directory, and +version. Vicinities express only the concept of a file environment +where a file name can be resolved to a file in a system independent +manner. Vicinities can even be used on "flat" file systems (which have +no directory structure) by having the vicinity express constraints on +the file name. On most systems a vicinity would be a string. All of +these procedures are file system dependent. + +These procedures are provided by all implementations. + + - Function: make-vicinity PATH + Returns the vicinity of PATH for use by `in-vicinity'. + + - Function: program-vicinity + Returns the vicinity of the currently loading Scheme code. For an + interpreter this would be the directory containing source code. + For a compiled system (with multiple files) this would be the + directory where the object or executable files are. If no file is + currently loading it the result is undefined. *Warning:* + `program-vicinity' can return incorrect values if your program + escapes back into a `load'. + + - Function: library-vicinity + Returns the vicinity of the shared Scheme library. + + - Function: implementation-vicinity + Returns the vicinity of the underlying Scheme implementation. This + vicinity will likely contain startup code and messages and a + compiler. + + - Function: user-vicinity + Returns the vicinity of the current directory of the user. On most + systems this is `""' (the empty string). + + - Function: home-vicinity + Returns the vicinity of the user's "HOME" directory, the directory + which typically contains files which customize a computer + environment for a user. If scheme is running without a user (eg. + a daemon) or if this concept is meaningless for the platform, then + `home-vicinity' returns `#f'. + + - Function: in-vicinity VICINITY FILENAME + Returns a filename suitable for use by `slib:load', + `slib:load-source', `slib:load-compiled', `open-input-file', + `open-output-file', etc. The returned filename is FILENAME in + VICINITY. `in-vicinity' should allow FILENAME to override + VICINITY when FILENAME is an absolute pathname and VICINITY is + equal to the value of `(user-vicinity)'. The behavior of + `in-vicinity' when FILENAME is absolute and VICINITY is not equal + to the value of `(user-vicinity)' is unspecified. For most systems + `in-vicinity' can be `string-append'. + + - Function: sub-vicinity VICINITY NAME + Returns the vicinity of VICINITY restricted to NAME. This is used + for large systems where names of files in subsystems could + conflict. On systems with directory structure `sub-vicinity' will + return a pathname of the subdirectory NAME of VICINITY. + + +File: slib.info, Node: Configuration, Next: Input/Output, Prev: Vicinity, Up: Built-in Support + +Configuration +------------- + +These constants and procedures describe characteristics of the Scheme +and underlying operating system. They are provided by all +implementations. + + - Constant: char-code-limit + An integer 1 larger that the largest value which can be returned by + `char->integer'. + + - Constant: most-positive-fixnum + In implementations which support integers of practically unlimited + size, MOST-POSITIVE-FIXNUM is a large exact integer within the + range of exact integers that may result from computing the length + of a list, vector, or string. + + In implementations which do not support integers of practically + unlimited size, MOST-POSITIVE-FIXNUM is the largest exact integer + that may result from computing the length of a list, vector, or + string. + + - Constant: slib:tab + The tab character. + + - Constant: slib:form-feed + The form-feed character. + + - Function: software-type + Returns a symbol denoting the generic operating system type. For + instance, `unix', `vms', `macos', `amiga', or `ms-dos'. + + - Function: slib:report-version + Displays the versions of SLIB and the underlying Scheme + implementation and the name of the operating system. An + unspecified value is returned. + + (slib:report-version) => slib "2c7" on scm "5b1" on unix | + + - Function: slib:report + Displays the information of `(slib:report-version)' followed by + almost all the information neccessary for submitting a problem + report. An unspecified value is returned. + + - Function: slib:report #T + provides a more verbose listing. + + - Function: slib:report FILENAME + Writes the report to file `filename'. + + (slib:report) + => + slib "2c7" on scm "5b1" on unix | + (implementation-vicinity) is "/home/jaffer/scm/" + (library-vicinity) is "/home/jaffer/slib/" + (scheme-file-suffix) is ".scm" + loaded *features* : + trace alist qp sort + common-list-functions macro values getopt + compiled + implementation *features* : + bignum complex real rational + inexact vicinity ed getenv + tmpnam abort transcript with-file + ieee-p1178 rev4-report rev4-optional-procedures hash + object-hash delay eval dynamic-wind + multiarg-apply multiarg/and- logical defmacro + string-port source current-time record + rev3-procedures rev2-procedures sun-dl string-case + array dump char-ready? full-continuation + system + implementation *catalog* : + (i/o-extensions compiled "/home/jaffer/scm/ioext.so") + ... + + +File: slib.info, Node: Input/Output, Next: Legacy, Prev: Configuration, Up: Built-in Support + +Input/Output +------------ + +These procedures are provided by all implementations. + + - Procedure: file-exists? FILENAME + Returns `#t' if the specified file exists. Otherwise, returns + `#f'. If the underlying implementation does not support this + feature then `#f' is always returned. + + - Procedure: delete-file FILENAME + Deletes the file specified by FILENAME. If FILENAME can not be + deleted, `#f' is returned. Otherwise, `#t' is returned. + + - Procedure: tmpnam + Returns a pathname for a file which will likely not be used by any + other process. Successive calls to `(tmpnam)' will return + different pathnames. + + - Procedure: current-error-port + Returns the current port to which diagnostic and error output is + directed. + + - Procedure: force-output + - Procedure: force-output PORT + Forces any pending output on PORT to be delivered to the output + device and returns an unspecified value. The PORT argument may be + omitted, in which case it defaults to the value returned by + `(current-output-port)'. + + - Procedure: output-port-width + - Procedure: output-port-width PORT + Returns the width of PORT, which defaults to + `(current-output-port)' if absent. If the width cannot be + determined 79 is returned. + + - Procedure: output-port-height + - Procedure: output-port-height PORT + Returns the height of PORT, which defaults to + `(current-output-port)' if absent. If the height cannot be + determined 24 is returned. + + +File: slib.info, Node: Legacy, Next: System, Prev: Input/Output, Up: Built-in Support + +Legacy +------ + + These procedures are provided by all implementations. + + - Function: identity X + IDENTITY returns its argument. + + Example: + (identity 3) + => 3 + (identity '(foo bar)) + => (foo bar) + (map identity LST) + == (copy-list LST) + +The following procedures were present in Scheme until R4RS (*note +Language changes: (r4rs)Notes.). They are provided by all SLIB +implementations. + + - Constant: t + Derfined as `#t'. + + - Constant: nil + Defined as `#f'. + + - Function: last-pair L + Returns the last pair in the list L. Example: + (last-pair (cons 1 2)) + => (1 . 2) + (last-pair '(1 2)) + => (2) + == (cons 2 '()) + + +File: slib.info, Node: System, Prev: Legacy, Up: Built-in Support + +System +------ + +These procedures are provided by all implementations. + + - Procedure: slib:load-source NAME + Loads a file of Scheme source code from NAME with the default + filename extension used in SLIB. For instance if the filename + extension used in SLIB is `.scm' then `(slib:load-source "foo")' + will load from file `foo.scm'. + + - Procedure: slib:load-compiled NAME + On implementations which support separtely loadable compiled + modules, loads a file of compiled code from NAME with the + implementation's filename extension for compiled code appended. + + - Procedure: slib:load NAME + Loads a file of Scheme source or compiled code from NAME with the + appropriate suffixes appended. If both source and compiled code + are present with the appropriate names then the implementation + will load just one. It is up to the implementation to choose + which one will be loaded. + + If an implementation does not support compiled code then + `slib:load' will be identical to `slib:load-source'. + + - Procedure: slib:eval OBJ + `eval' returns the value of OBJ evaluated in the current top level + environment. *Note Eval:: provides a more general evaluation + facility. + + - Procedure: slib:eval-load FILENAME EVAL + FILENAME should be a string. If filename names an existing file, + the Scheme source code expressions and definitions are read from + the file and EVAL called with them sequentially. The + `slib:eval-load' procedure does not affect the values returned by + `current-input-port' and `current-output-port'. + + - Procedure: slib:warn ARG1 ARG2 ... + Outputs a warning message containing the arguments. + + - Procedure: slib:error ARG1 ARG2 ... + Outputs an error message containing the arguments, aborts + evaluation of the current form and responds in a system dependent + way to the error. Typical responses are to abort the program or + to enter a read-eval-print loop. + + - Procedure: slib:exit N + - Procedure: slib:exit + Exits from the Scheme session returning status N to the system. + If N is omitted or `#t', a success status is returned to the + system (if possible). If N is `#f' a failure is returned to the + system (if possible). If N is an integer, then N is returned to + the system (if possible). If the Scheme session cannot exit an + unspecified value is returned from `slib:exit'. + + +File: slib.info, Node: About this manual, Prev: Built-in Support, Up: The Library System + +About this manual +================= + + * Entries that are labeled as Functions are called for their return + values. Entries that are labeled as Procedures are called + primarily for their side effects. + + * Examples in this text were produced using the `scm' Scheme + implementation. + + * At the beginning of each section, there is a line that looks like + `(require 'feature)'. Include this line in your code prior to + using the package. + + +File: slib.info, Node: Scheme Syntax Extension Packages, Next: Textual Conversion Packages, Prev: The Library System, Up: Top + +Scheme Syntax Extension Packages +******************************** + +* Menu: + +* Defmacro:: Supported by all implementations + +* R4RS Macros:: 'macro +* Macro by Example:: 'macro-by-example +* Macros That Work:: 'macros-that-work +* Syntactic Closures:: 'syntactic-closures +* Syntax-Case Macros:: 'syntax-case + +Syntax extensions (macros) included with SLIB. Also *Note Structures::. + +* Fluid-Let:: 'fluid-let +* Yasos:: 'yasos, 'oop, 'collect + + +File: slib.info, Node: Defmacro, Next: R4RS Macros, Prev: Scheme Syntax Extension Packages, Up: Scheme Syntax Extension Packages + +Defmacro +======== + + Defmacros are supported by all implementations. + + - Function: gentemp + Returns a new (interned) symbol each time it is called. The symbol + names are implementation-dependent + (gentemp) => scm:G0 + (gentemp) => scm:G1 + + - Function: defmacro:eval E + Returns the `slib:eval' of expanding all defmacros in scheme + expression E. + + - Function: defmacro:load FILENAME + FILENAME should be a string. If filename names an existing file, + the `defmacro:load' procedure reads Scheme source code expressions + and definitions from the file and evaluates them sequentially. + These source code expressions and definitions may contain defmacro + definitions. The `macro:load' procedure does not affect the values + returned by `current-input-port' and `current-output-port'. + + - Function: defmacro? SYM + Returns `#t' if SYM has been defined by `defmacro', `#f' otherwise. + + - Function: macroexpand-1 FORM + - Function: macroexpand FORM + If FORM is a macro call, `macroexpand-1' will expand the macro + call once and return it. A FORM is considered to be a macro call + only if it is a cons whose `car' is a symbol for which a `defmacr' + has been defined. + + `macroexpand' is similar to `macroexpand-1', but repeatedly + expands FORM until it is no longer a macro call. + + - Macro: defmacro NAME LAMBDA-LIST FORM ... + When encountered by `defmacro:eval', `defmacro:macroexpand*', or + `defmacro:load' defines a new macro which will henceforth be + expanded when encountered by `defmacro:eval', + `defmacro:macroexpand*', or `defmacro:load'. + +Defmacroexpand +-------------- + + `(require 'defmacroexpand)' + + - Function: defmacro:expand* E + Returns the result of expanding all defmacros in scheme expression + E. + + +File: slib.info, Node: R4RS Macros, Next: Macro by Example, Prev: Defmacro, Up: Scheme Syntax Extension Packages + +R4RS Macros +=========== + + `(require 'macro)' is the appropriate call if you want R4RS +high-level macros but don't care about the low level implementation. If +an SLIB R4RS macro implementation is already loaded it will be used. +Otherwise, one of the R4RS macros implemetations is loaded. + + The SLIB R4RS macro implementations support the following uniform +interface: + + - Function: macro:expand SEXPRESSION + Takes an R4RS expression, macro-expands it, and returns the result + of the macro expansion. + + - Function: macro:eval SEXPRESSION + Takes an R4RS expression, macro-expands it, evals the result of the + macro expansion, and returns the result of the evaluation. + + - Procedure: macro:load FILENAME + FILENAME should be a string. If filename names an existing file, + the `macro:load' procedure reads Scheme source code expressions and + definitions from the file and evaluates them sequentially. These + source code expressions and definitions may contain macro + definitions. The `macro:load' procedure does not affect the + values returned by `current-input-port' and `current-output-port'. + + +File: slib.info, Node: Macro by Example, Next: Macros That Work, Prev: R4RS Macros, Up: Scheme Syntax Extension Packages + +Macro by Example +================ + + `(require 'macro-by-example)' + + A vanilla implementation of `Macro by Example' (Eugene Kohlbecker, +R4RS) by Dorai Sitaram, (dorai@cs.rice.edu) using `defmacro'. + + * generating hygienic global `define-syntax' Macro-by-Example macros + *cheaply*. + + * can define macros which use `...'. + + * needn't worry about a lexical variable in a macro definition + clashing with a variable from the macro use context + + * don't suffer the overhead of redefining the repl if `defmacro' + natively supported (most implementations) + +Caveat +------ + + These macros are not referentially transparent (*note Macros: +(r4rs)Macros.). Lexically scoped macros (i.e., `let-syntax' and +`letrec-syntax') are not supported. In any case, the problem of +referential transparency gains poignancy only when `let-syntax' and +`letrec-syntax' are used. So you will not be courting large-scale +disaster unless you're using system-function names as local variables +with unintuitive bindings that the macro can't use. However, if you +must have the full `r4rs' macro functionality, look to the more +featureful (but also more expensive) versions of syntax-rules available +in slib *Note Macros That Work::, *Note Syntactic Closures::, and *Note +Syntax-Case Macros::. + + - Macro: define-syntax KEYWORD TRANSFORMER-SPEC + The KEYWORD is an identifier, and the TRANSFORMER-SPEC should be + an instance of `syntax-rules'. + + The top-level syntactic environment is extended by binding the + KEYWORD to the specified transformer. + + (define-syntax let* + (syntax-rules () + ((let* () body1 body2 ...) + (let () body1 body2 ...)) + ((let* ((name1 val1) (name2 val2) ...) + body1 body2 ...) + (let ((name1 val1)) + (let* (( name2 val2) ...) + body1 body2 ...))))) + + - Macro: syntax-rules LITERALS SYNTAX-RULE ... + LITERALS is a list of identifiers, and each SYNTAX-RULE should be + of the form + + `(PATTERN TEMPLATE)' + + where the PATTERN and TEMPLATE are as in the grammar above. + + An instance of `syntax-rules' produces a new macro transformer by + specifying a sequence of hygienic rewrite rules. A use of a macro + whose keyword is associated with a transformer specified by + `syntax-rules' is matched against the patterns contained in the + SYNTAX-RULEs, beginning with the leftmost SYNTAX-RULE. When a + match is found, the macro use is trancribed hygienically according + to the template. + + Each pattern begins with the keyword for the macro. This keyword + is not involved in the matching and is not considered a pattern + variable or literal identifier. + + +File: slib.info, Node: Macros That Work, Next: Syntactic Closures, Prev: Macro by Example, Up: Scheme Syntax Extension Packages + +Macros That Work +================ + + `(require 'macros-that-work)' + + `Macros That Work' differs from the other R4RS macro implementations +in that it does not expand derived expression types to primitive +expression types. + + - Function: macro:expand EXPRESSION + - Function: macwork:expand EXPRESSION + Takes an R4RS expression, macro-expands it, and returns the result + of the macro expansion. + + - Function: macro:eval EXPRESSION + - Function: macwork:eval EXPRESSION + `macro:eval' returns the value of EXPRESSION in the current top + level environment. EXPRESSION can contain macro definitions. + Side effects of EXPRESSION will affect the top level environment. + + - Procedure: macro:load FILENAME + - Procedure: macwork:load FILENAME + FILENAME should be a string. If filename names an existing file, + the `macro:load' procedure reads Scheme source code expressions and + definitions from the file and evaluates them sequentially. These + source code expressions and definitions may contain macro + definitions. The `macro:load' procedure does not affect the + values returned by `current-input-port' and `current-output-port'. + + References: + + The `Revised^4 Report on the Algorithmic Language Scheme' Clinger and +Rees [editors]. To appear in LISP Pointers. Also available as a +technical report from the University of Oregon, MIT AI Lab, and Cornell. + + Macros That Work. Clinger and Rees. POPL '91. + + The supported syntax differs from the R4RS in that vectors are allowed +as patterns and as templates and are not allowed as pattern or template +data. + + transformer spec ==> (syntax-rules literals rules) + + rules ==> () + | (rule . rules) + + rule ==> (pattern template) + + pattern ==> pattern_var ; a symbol not in literals + | symbol ; a symbol in literals + | () + | (pattern . pattern) + | (ellipsis_pattern) + | #(pattern*) ; extends R4RS + | #(pattern* ellipsis_pattern) ; extends R4RS + | pattern_datum + + template ==> pattern_var + | symbol + | () + | (template2 . template2) + | #(template*) ; extends R4RS + | pattern_datum + + template2 ==> template + | ellipsis_template + + pattern_datum ==> string ; no vector + | character + | boolean + | number + + ellipsis_pattern ==> pattern ... + + ellipsis_template ==> template ... + + pattern_var ==> symbol ; not in literals + + literals ==> () + | (symbol . literals) + +Definitions +----------- + +Scope of an ellipsis + Within a pattern or template, the scope of an ellipsis (`...') is + the pattern or template that appears to its left. + +Rank of a pattern variable + The rank of a pattern variable is the number of ellipses within + whose scope it appears in the pattern. + +Rank of a subtemplate + The rank of a subtemplate is the number of ellipses within whose + scope it appears in the template. + +Template rank of an occurrence of a pattern variable + The template rank of an occurrence of a pattern variable within a + template is the rank of that occurrence, viewed as a subtemplate. + +Variables bound by a pattern + The variables bound by a pattern are the pattern variables that + appear within it. + +Referenced variables of a subtemplate + The referenced variables of a subtemplate are the pattern + variables that appear within it. + +Variables opened by an ellipsis template + The variables opened by an ellipsis template are the referenced + pattern variables whose rank is greater than the rank of the + ellipsis template. + +Restrictions +------------ + + No pattern variable appears more than once within a pattern. + + For every occurrence of a pattern variable within a template, the +template rank of the occurrence must be greater than or equal to the +pattern variable's rank. + + Every ellipsis template must open at least one variable. + + For every ellipsis template, the variables opened by an ellipsis +template must all be bound to sequences of the same length. + + The compiled form of a RULE is + + rule ==> (pattern template inserted) + + pattern ==> pattern_var + | symbol + | () + | (pattern . pattern) + | ellipsis_pattern + | #(pattern) + | pattern_datum + + template ==> pattern_var + | symbol + | () + | (template2 . template2) + | #(pattern) + | pattern_datum + + template2 ==> template + | ellipsis_template + + pattern_datum ==> string + | character + | boolean + | number + + pattern_var ==> #(V symbol rank) + + ellipsis_pattern ==> #(E pattern pattern_vars) + + ellipsis_template ==> #(E template pattern_vars) + + inserted ==> () + | (symbol . inserted) + + pattern_vars ==> () + | (pattern_var . pattern_vars) + + rank ==> exact non-negative integer + + where V and E are unforgeable values. + + The pattern variables associated with an ellipsis pattern are the +variables bound by the pattern, and the pattern variables associated +with an ellipsis template are the variables opened by the ellipsis +template. + + If the template contains a big chunk that contains no pattern +variables or inserted identifiers, then the big chunk will be copied +unnecessarily. That shouldn't matter very often. + + +File: slib.info, Node: Syntactic Closures, Next: Syntax-Case Macros, Prev: Macros That Work, Up: Scheme Syntax Extension Packages + +Syntactic Closures +================== + + `(require 'syntactic-closures)' + + - Function: macro:expand EXPRESSION + - Function: synclo:expand EXPRESSION + Returns scheme code with the macros and derived expression types of + EXPRESSION expanded to primitive expression types. + + - Function: macro:eval EXPRESSION + - Function: synclo:eval EXPRESSION + `macro:eval' returns the value of EXPRESSION in the current top + level environment. EXPRESSION can contain macro definitions. + Side effects of EXPRESSION will affect the top level environment. + + - Procedure: macro:load FILENAME + - Procedure: synclo:load FILENAME + FILENAME should be a string. If filename names an existing file, + the `macro:load' procedure reads Scheme source code expressions and + definitions from the file and evaluates them sequentially. These + source code expressions and definitions may contain macro + definitions. The `macro:load' procedure does not affect the + values returned by `current-input-port' and `current-output-port'. + +Syntactic Closure Macro Facility +-------------------------------- + + A Syntactic Closures Macro Facility + + by Chris Hanson + + 9 November 1991 + + This document describes "syntactic closures", a low-level macro +facility for the Scheme programming language. The facility is an +alternative to the low-level macro facility described in the `Revised^4 +Report on Scheme.' This document is an addendum to that report. + + The syntactic closures facility extends the BNF rule for TRANSFORMER +SPEC to allow a new keyword that introduces a low-level macro +transformer: + TRANSFORMER SPEC := (transformer EXPRESSION) + + Additionally, the following procedures are added: + make-syntactic-closure + capture-syntactic-environment + identifier? + identifier=? + + The description of the facility is divided into three parts. The +first part defines basic terminology. The second part describes how +macro transformers are defined. The third part describes the use of +"identifiers", which extend the syntactic closure mechanism to be +compatible with `syntax-rules'. + +Terminology +........... + + This section defines the concepts and data types used by the syntactic +closures facility. + + * "Forms" are the syntactic entities out of which programs are + recursively constructed. A form is any expression, any + definition, any syntactic keyword, or any syntactic closure. The + variable name that appears in a `set!' special form is also a + form. Examples of forms: + 17 + #t + car + (+ x 4) + (lambda (x) x) + (define pi 3.14159) + if + define + + * An "alias" is an alternate name for a given symbol. It can appear + anywhere in a form that the symbol could be used, and when quoted + it is replaced by the symbol; however, it does not satisfy the + predicate `symbol?'. Macro transformers rarely distinguish + symbols from aliases, referring to both as identifiers. + + * A "syntactic" environment maps identifiers to their meanings. + More precisely, it determines whether an identifier is a syntactic + keyword or a variable. If it is a keyword, the meaning is an + interpretation for the form in which that keyword appears. If it + is a variable, the meaning identifies which binding of that + variable is referenced. In short, syntactic environments contain + all of the contextual information necessary for interpreting the + meaning of a particular form. + + * A "syntactic closure" consists of a form, a syntactic environment, + and a list of identifiers. All identifiers in the form take their + meaning from the syntactic environment, except those in the given + list. The identifiers in the list are to have their meanings + determined later. A syntactic closure may be used in any context + in which its form could have been used. Since a syntactic closure + is also a form, it may not be used in contexts where a form would + be illegal. For example, a form may not appear as a clause in the + cond special form. A syntactic closure appearing in a quoted + structure is replaced by its form. + +Transformer Definition +...................... + + This section describes the `transformer' special form and the +procedures `make-syntactic-closure' and `capture-syntactic-environment'. + + - Syntax: transformer EXPRESSION + Syntax: It is an error if this syntax occurs except as a + TRANSFORMER SPEC. + + Semantics: The EXPRESSION is evaluated in the standard transformer + environment to yield a macro transformer as described below. This + macro transformer is bound to a macro keyword by the special form + in which the `transformer' expression appears (for example, + `let-syntax'). + + A "macro transformer" is a procedure that takes two arguments, a + form and a syntactic environment, and returns a new form. The + first argument, the "input form", is the form in which the macro + keyword occurred. The second argument, the "usage environment", + is the syntactic environment in which the input form occurred. + The result of the transformer, the "output form", is automatically + closed in the "transformer environment", which is the syntactic + environment in which the `transformer' expression occurred. + + For example, here is a definition of a push macro using + `syntax-rules': + (define-syntax push + (syntax-rules () + ((push item list) + (set! list (cons item list))))) + + Here is an equivalent definition using `transformer': + (define-syntax push + (transformer + (lambda (exp env) + (let ((item + (make-syntactic-closure env '() (cadr exp))) + (list + (make-syntactic-closure env '() (caddr exp)))) + `(set! ,list (cons ,item ,list)))))) + + In this example, the identifiers `set!' and `cons' are closed in + the transformer environment, and thus will not be affected by the + meanings of those identifiers in the usage environment `env'. + + Some macros may be non-hygienic by design. For example, the + following defines a loop macro that implicitly binds `exit' to an + escape procedure. The binding of `exit' is intended to capture + free references to `exit' in the body of the loop, so `exit' must + be left free when the body is closed: + (define-syntax loop + (transformer + (lambda (exp env) + (let ((body (cdr exp))) + `(call-with-current-continuation + (lambda (exit) + (let f () + ,@(map (lambda (exp) + (make-syntactic-closure env '(exit) + exp)) + body) + (f)))))))) + + To assign meanings to the identifiers in a form, use + `make-syntactic-closure' to close the form in a syntactic + environment. + + - Function: make-syntactic-closure ENVIRONMENT FREE-NAMES FORM + ENVIRONMENT must be a syntactic environment, FREE-NAMES must be a + list of identifiers, and FORM must be a form. + `make-syntactic-closure' constructs and returns a syntactic closure + of FORM in ENVIRONMENT, which can be used anywhere that FORM could + have been used. All the identifiers used in FORM, except those + explicitly excepted by FREE-NAMES, obtain their meanings from + ENVIRONMENT. + + Here is an example where FREE-NAMES is something other than the + empty list. It is instructive to compare the use of FREE-NAMES in + this example with its use in the `loop' example above: the examples + are similar except for the source of the identifier being left + free. + (define-syntax let1 + (transformer + (lambda (exp env) + (let ((id (cadr exp)) + (init (caddr exp)) + (exp (cadddr exp))) + `((lambda (,id) + ,(make-syntactic-closure env (list id) exp)) + ,(make-syntactic-closure env '() init)))))) + + `let1' is a simplified version of `let' that only binds a single + identifier, and whose body consists of a single expression. When + the body expression is syntactically closed in its original + syntactic environment, the identifier that is to be bound by + `let1' must be left free, so that it can be properly captured by + the `lambda' in the output form. + + To obtain a syntactic environment other than the usage + environment, use `capture-syntactic-environment'. + + - Function: capture-syntactic-environment PROCEDURE + `capture-syntactic-environment' returns a form that will, when + transformed, call PROCEDURE on the current syntactic environment. + PROCEDURE should compute and return a new form to be transformed, + in that same syntactic environment, in place of the form. + + An example will make this clear. Suppose we wanted to define a + simple `loop-until' keyword equivalent to + (define-syntax loop-until + (syntax-rules () + ((loop-until id init test return step) + (letrec ((loop + (lambda (id) + (if test return (loop step))))) + (loop init))))) + + The following attempt at defining `loop-until' has a subtle bug: + (define-syntax loop-until + (transformer + (lambda (exp env) + (let ((id (cadr exp)) + (init (caddr exp)) + (test (cadddr exp)) + (return (cadddr (cdr exp))) + (step (cadddr (cddr exp))) + (close + (lambda (exp free) + (make-syntactic-closure env free exp)))) + `(letrec ((loop + (lambda (,id) + (if ,(close test (list id)) + ,(close return (list id)) + (loop ,(close step (list id))))))) + (loop ,(close init '()))))))) + + This definition appears to take all of the proper precautions to + prevent unintended captures. It carefully closes the + subexpressions in their original syntactic environment and it + leaves the `id' identifier free in the `test', `return', and + `step' expressions, so that it will be captured by the binding + introduced by the `lambda' expression. Unfortunately it uses the + identifiers `if' and `loop' within that `lambda' expression, so if + the user of `loop-until' just happens to use, say, `if' for the + identifier, it will be inadvertently captured. + + The syntactic environment that `if' and `loop' want to be exposed + to is the one just outside the `lambda' expression: before the + user's identifier is added to the syntactic environment, but after + the identifier loop has been added. + `capture-syntactic-environment' captures exactly that environment + as follows: + (define-syntax loop-until + (transformer + (lambda (exp env) + (let ((id (cadr exp)) + (init (caddr exp)) + (test (cadddr exp)) + (return (cadddr (cdr exp))) + (step (cadddr (cddr exp))) + (close + (lambda (exp free) + (make-syntactic-closure env free exp)))) + `(letrec ((loop + ,(capture-syntactic-environment + (lambda (env) + `(lambda (,id) + (,(make-syntactic-closure env '() `if) + ,(close test (list id)) + ,(close return (list id)) + (,(make-syntactic-closure env '() + `loop) + ,(close step (list id))))))))) + (loop ,(close init '()))))))) + + In this case, having captured the desired syntactic environment, + it is convenient to construct syntactic closures of the + identifiers `if' and the `loop' and use them in the body of the + `lambda'. + + A common use of `capture-syntactic-environment' is to get the + transformer environment of a macro transformer: + (transformer + (lambda (exp env) + (capture-syntactic-environment + (lambda (transformer-env) + ...)))) + +Identifiers +........... + + This section describes the procedures that create and manipulate +identifiers. Previous syntactic closure proposals did not have an +identifier data type - they just used symbols. The identifier data +type extends the syntactic closures facility to be compatible with the +high-level `syntax-rules' facility. + + As discussed earlier, an identifier is either a symbol or an "alias". +An alias is implemented as a syntactic closure whose "form" is an +identifier: + (make-syntactic-closure env '() 'a) + => an "alias" + + Aliases are implemented as syntactic closures because they behave just +like syntactic closures most of the time. The difference is that an +alias may be bound to a new value (for example by `lambda' or +`let-syntax'); other syntactic closures may not be used this way. If +an alias is bound, then within the scope of that binding it is looked +up in the syntactic environment just like any other identifier. + + Aliases are used in the implementation of the high-level facility +`syntax-rules'. A macro transformer created by `syntax-rules' uses a +template to generate its output form, substituting subforms of the +input form into the template. In a syntactic closures implementation, +all of the symbols in the template are replaced by aliases closed in +the transformer environment, while the output form itself is closed in +the usage environment. This guarantees that the macro transformation +is hygienic, without requiring the transformer to know the syntactic +roles of the substituted input subforms. + + - Function: identifier? OBJECT + Returns `#t' if OBJECT is an identifier, otherwise returns `#f'. + Examples: + (identifier? 'a) + => #t + (identifier? (make-syntactic-closure env '() 'a)) + => #t + (identifier? "a") + => #f + (identifier? #\a) + => #f + (identifier? 97) + => #f + (identifier? #f) + => #f + (identifier? '(a)) + => #f + (identifier? '#(a)) + => #f + + The predicate `eq?' is used to determine if two identifers are + "the same". Thus `eq?' can be used to compare identifiers exactly + as it would be used to compare symbols. Often, though, it is + useful to know whether two identifiers "mean the same thing". For + example, the `cond' macro uses the symbol `else' to identify the + final clause in the conditional. A macro transformer for `cond' + cannot just look for the symbol `else', because the `cond' form + might be the output of another macro transformer that replaced the + symbol `else' with an alias. Instead the transformer must look + for an identifier that "means the same thing" in the usage + environment as the symbol `else' means in the transformer + environment. + + - Function: identifier=? ENVIRONMENT1 IDENTIFIER1 ENVIRONMENT2 + IDENTIFIER2 + ENVIRONMENT1 and ENVIRONMENT2 must be syntactic environments, and + IDENTIFIER1 and IDENTIFIER2 must be identifiers. `identifier=?' + returns `#t' if the meaning of IDENTIFIER1 in ENVIRONMENT1 is the + same as that of IDENTIFIER2 in ENVIRONMENT2, otherwise it returns + `#f'. Examples: + + (let-syntax + ((foo + (transformer + (lambda (form env) + (capture-syntactic-environment + (lambda (transformer-env) + (identifier=? transformer-env 'x env 'x))))))) + (list (foo) + (let ((x 3)) + (foo)))) + => (#t #f) + + (let-syntax ((bar foo)) + (let-syntax + ((foo + (transformer + (lambda (form env) + (capture-syntactic-environment + (lambda (transformer-env) + (identifier=? transformer-env 'foo + env (cadr form)))))))) + (list (foo foo) + (foobar)))) + => (#f #t) + +Acknowledgements +................ + + The syntactic closures facility was invented by Alan Bawden and +Jonathan Rees. The use of aliases to implement `syntax-rules' was +invented by Alan Bawden (who prefers to call them "synthetic names"). +Much of this proposal is derived from an earlier proposal by Alan +Bawden. + + +File: slib.info, Node: Syntax-Case Macros, Next: Fluid-Let, Prev: Syntactic Closures, Up: Scheme Syntax Extension Packages + +Syntax-Case Macros +================== + + `(require 'syntax-case)' + + - Function: macro:expand EXPRESSION + - Function: syncase:expand EXPRESSION + Returns scheme code with the macros and derived expression types of + EXPRESSION expanded to primitive expression types. + + - Function: macro:eval EXPRESSION + - Function: syncase:eval EXPRESSION + `macro:eval' returns the value of EXPRESSION in the current top + level environment. EXPRESSION can contain macro definitions. + Side effects of EXPRESSION will affect the top level environment. + + - Procedure: macro:load FILENAME + - Procedure: syncase:load FILENAME + FILENAME should be a string. If filename names an existing file, + the `macro:load' procedure reads Scheme source code expressions and + definitions from the file and evaluates them sequentially. These + source code expressions and definitions may contain macro + definitions. The `macro:load' procedure does not affect the + values returned by `current-input-port' and `current-output-port'. + + This is version 2.1 of `syntax-case', the low-level macro facility +proposed and implemented by Robert Hieb and R. Kent Dybvig. + + This version is further adapted by Harald Hanche-Olsen + to make it compatible with, and easily usable +with, SLIB. Mainly, these adaptations consisted of: + + * Removing white space from `expand.pp' to save space in the + distribution. This file is not meant for human readers anyway... + + * Removed a couple of Chez scheme dependencies. + + * Renamed global variables used to minimize the possibility of name + conflicts. + + * Adding an SLIB-specific initialization file. + + * Removing a couple extra files, most notably the documentation (but + see below). + + If you wish, you can see exactly what changes were done by reading the +shell script in the file `syncase.sh'. + + The two PostScript files were omitted in order to not burden the SLIB +distribution with them. If you do intend to use `syntax-case', +however, you should get these files and print them out on a PostScript +printer. They are available with the original `syntax-case' +distribution by anonymous FTP in +`cs.indiana.edu:/pub/scheme/syntax-case'. + + In order to use syntax-case from an interactive top level, execute: + (require 'syntax-case) + (require 'repl) + (repl:top-level macro:eval) + See the section Repl (*note Repl::.) for more information. + + To check operation of syntax-case get +`cs.indiana.edu:/pub/scheme/syntax-case', and type + (require 'syntax-case) + (syncase:sanity-check) + + Beware that `syntax-case' takes a long time to load - about 20s on a +SPARCstation SLC (with SCM) and about 90s on a Macintosh SE/30 (with +Gambit). + +Notes +----- + + All R4RS syntactic forms are defined, including `delay'. Along with +`delay' are simple definitions for `make-promise' (into which `delay' +expressions expand) and `force'. + + `syntax-rules' and `with-syntax' (described in `TR356') are defined. + + `syntax-case' is actually defined as a macro that expands into calls +to the procedure `syntax-dispatch' and the core form `syntax-lambda'; +do not redefine these names. + + Several other top-level bindings not documented in TR356 are created: + * the "hooks" in `hooks.ss' + + * the `build-' procedures in `output.ss' + + * `expand-syntax' (the expander) + + The syntax of define has been extended to allow `(define ID)', which +assigns ID to some unspecified value. + + We have attempted to maintain R4RS compatibility where possible. The +incompatibilities should be confined to `hooks.ss'. Please let us know +if there is some incompatibility that is not flagged as such. + + Send bug reports, comments, suggestions, and questions to Kent Dybvig +(dyb@iuvax.cs.indiana.edu). + +Note from maintainer +-------------------- + + Included with the `syntax-case' files was `structure.scm' which +defines a macro `define-structure'. There is no documentation for this +macro and it is not used by any code in SLIB. + + +File: slib.info, Node: Fluid-Let, Next: Yasos, Prev: Syntax-Case Macros, Up: Scheme Syntax Extension Packages + +Fluid-Let +========= + + `(require 'fluid-let)' + + - Syntax: fluid-let `(BINDINGS ...)' FORMS... + + (fluid-let ((VARIABLE INIT) ...) + EXPRESSION EXPRESSION ...) + + The INITs are evaluated in the current environment (in some +unspecified order), the current values of the VARIABLEs are saved, the +results are assigned to the VARIABLEs, the EXPRESSIONs are evaluated +sequentially in the current environment, the VARIABLEs are restored to +their original values, and the value of the last EXPRESSION is returned. + + The syntax of this special form is similar to that of `let', but +`fluid-let' temporarily rebinds existing VARIABLEs. Unlike `let', +`fluid-let' creates no new bindings; instead it *assigns* the values of +each INIT to the binding (determined by the rules of lexical scoping) +of its corresponding VARIABLE. + + +File: slib.info, Node: Yasos, Prev: Fluid-Let, Up: Scheme Syntax Extension Packages + +Yasos +===== + + `(require 'oop)' or `(require 'yasos)' + + `Yet Another Scheme Object System' is a simple object system for +Scheme based on the paper by Norman Adams and Jonathan Rees: `Object +Oriented Programming in Scheme', Proceedings of the 1988 ACM Conference +on LISP and Functional Programming, July 1988 [ACM #552880]. + + Another reference is: + + Ken Dickey. Scheming with Objects `AI Expert' Volume 7, Number 10 +(October 1992), pp. 24-33. + +* Menu: + +* Yasos terms:: Definitions and disclaimer. +* Yasos interface:: The Yasos macros and procedures. +* Setters:: Dylan-like setters in Yasos. +* Yasos examples:: Usage of Yasos and setters. + + +File: slib.info, Node: Yasos terms, Next: Yasos interface, Prev: Yasos, Up: Yasos + +Terms +----- + +"Object" + Any Scheme data object. + +"Instance" + An instance of the OO system; an "object". + +"Operation" + A METHOD. + +*Notes:* + The object system supports multiple inheritance. An instance can + inherit from 0 or more ancestors. In the case of multiple + inherited operations with the same identity, the operation used is + that from the first ancestor which contains it (in the ancestor + `let'). An operation may be applied to any Scheme data + object--not just instances. As code which creates instances is + just code, there are no "classes" and no meta-ANYTHING. Method + dispatch is by a procedure call a la CLOS rather than by `send' + syntax a la Smalltalk. + +*Disclaimer:* + There are a number of optimizations which can be made. This + implementation is expository (although performance should be quite + reasonable). See the L&FP paper for some suggestions. + + +File: slib.info, Node: Yasos interface, Next: Setters, Prev: Yasos terms, Up: Yasos + +Interface +--------- + + - Syntax: define-operation `('OPNAME SELF ARG ...`)' DEFAULT-BODY + Defines a default behavior for data objects which don't handle the + operation OPNAME. The default behavior (for an empty + DEFAULT-BODY) is to generate an error. + + - Syntax: define-predicate OPNAME? + Defines a predicate OPNAME?, usually used for determining the + "type" of an object, such that `(OPNAME? OBJECT)' returns `#t' if + OBJECT has an operation OPNAME? and `#f' otherwise. + + - Syntax: object `((NAME SELF ARG ...) BODY)' ... + Returns an object (an instance of the object system) with + operations. Invoking `(NAME OBJECT ARG ...' executes the BODY of + the OBJECT with SELF bound to OBJECT and with argument(s) ARG.... + + - Syntax: object-with-ancestors `(('ANCESTOR1 INIT1`)' ...`)' + OPERATION ... + A `let'-like form of `object' for multiple inheritance. It + returns an object inheriting the behaviour of ANCESTOR1 etc. An + operation will be invoked in an ancestor if the object itself does + not provide such a method. In the case of multiple inherited + operations with the same identity, the operation used is the one + found in the first ancestor in the ancestor list. + + - Syntax: operate-as COMPONENT OPERATION SELF ARG ... + Used in an operation definition (of SELF) to invoke the OPERATION + in an ancestor COMPONENT but maintain the object's identity. Also + known as "send-to-super". + + - Procedure: print OBJ PORT + A default `print' operation is provided which is just `(format + PORT OBJ)' (*note Format::.) for non-instances and prints OBJ + preceded by `#' for instances. + + - Function: size OBJ + The default method returns the number of elements in OBJ if it is + a vector, string or list, `2' for a pair, `1' for a character and + by default id an error otherwise. Objects such as collections + (*note Collections::.) may override the default in an obvious way. + + +File: slib.info, Node: Setters, Next: Yasos examples, Prev: Yasos interface, Up: Yasos + +Setters +------- + + "Setters" implement "generalized locations" for objects associated +with some sort of mutable state. A "getter" operation retrieves a +value from a generalized location and the corresponding setter +operation stores a value into the location. Only the getter is named - +the setter is specified by a procedure call as below. (Dylan uses +special syntax.) Typically, but not necessarily, getters are access +operations to extract values from Yasos objects (*note Yasos::.). +Several setters are predefined, corresponding to getters `car', `cdr', +`string-ref' and `vector-ref' e.g., `(setter car)' is equivalent to +`set-car!'. + + This implementation of setters is similar to that in Dylan(TM) +(`Dylan: An object-oriented dynamic language', Apple Computer Eastern +Research and Technology). Common LISP provides similar facilities +through `setf'. + + - Function: setter GETTER + Returns the setter for the procedure GETTER. E.g., since + `string-ref' is the getter corresponding to a setter which is + actually `string-set!': + (define foo "foo") + ((setter string-ref) foo 0 #\F) ; set element 0 of foo + foo => "Foo" + + - Syntax: set PLACE NEW-VALUE + If PLACE is a variable name, `set' is equivalent to `set!'. + Otherwise, PLACE must have the form of a procedure call, where the + procedure name refers to a getter and the call indicates an + accessible generalized location, i.e., the call would return a + value. The return value of `set' is usually unspecified unless + used with a setter whose definition guarantees to return a useful + value. + (set (string-ref foo 2) #\O) ; generalized location with getter + foo => "FoO" + (set foo "foo") ; like set! + foo => "foo" + + - Procedure: add-setter GETTER SETTER + Add procedures GETTER and SETTER to the (inaccessible) list of + valid setter/getter pairs. SETTER implements the store operation + corresponding to the GETTER access operation for the relevant + state. The return value is unspecified. + + - Procedure: remove-setter-for GETTER + Removes the setter corresponding to the specified GETTER from the + list of valid setters. The return value is unspecified. + + - Syntax: define-access-operation GETTER-NAME + Shorthand for a Yasos `define-operation' defining an operation + GETTER-NAME that objects may support to return the value of some + mutable state. The default operation is to signal an error. The + return value is unspecified. + + +File: slib.info, Node: Yasos examples, Prev: Setters, Up: Yasos + +Examples +-------- + + ;;; These definitions for PRINT and SIZE are + ;;; already supplied by + (require 'yasos) + + (define-operation (print obj port) + (format port + (if (instance? obj) "#" "~s") + obj)) + + (define-operation (size obj) + (cond + ((vector? obj) (vector-length obj)) + ((list? obj) (length obj)) + ((pair? obj) 2) + ((string? obj) (string-length obj)) + ((char? obj) 1) + (else + (error "Operation not supported: size" obj)))) + + (define-predicate cell?) + (define-operation (fetch obj)) + (define-operation (store! obj newValue)) + + (define (make-cell value) + (object + ((cell? self) #t) + ((fetch self) value) + ((store! self newValue) + (set! value newValue) + newValue) + ((size self) 1) + ((print self port) + (format port "#" (fetch self))))) + + (define-operation (discard obj value) + (format #t "Discarding ~s~%" value)) + + (define (make-filtered-cell value filter) + (object-with-ancestors + ((cell (make-cell value))) + ((store! self newValue) + (if (filter newValue) + (store! cell newValue) + (discard self newValue))))) + + (define-predicate array?) + (define-operation (array-ref array index)) + (define-operation (array-set! array index value)) + + (define (make-array num-slots) + (let ((anArray (make-vector num-slots))) + (object + ((array? self) #t) + ((size self) num-slots) + ((array-ref self index) + (vector-ref anArray index)) + ((array-set! self index newValue) + (vector-set! anArray index newValue)) + ((print self port) + (format port "#" (size self)))))) + + (define-operation (position obj)) + (define-operation (discarded-value obj)) + + (define (make-cell-with-history value filter size) + (let ((pos 0) (most-recent-discard #f)) + (object-with-ancestors + ((cell (make-filtered-call value filter)) + (sequence (make-array size))) + ((array? self) #f) + ((position self) pos) + ((store! self newValue) + (operate-as cell store! self newValue) + (array-set! self pos newValue) + (set! pos (+ pos 1))) + ((discard self value) + (set! most-recent-discard value)) + ((discarded-value self) most-recent-discard) + ((print self port) + (format port "#" + (fetch self)))))) + + (define-access-operation fetch) + (add-setter fetch store!) + (define foo (make-cell 1)) + (print foo #f) + => "#" + (set (fetch foo) 2) + => + (print foo #f) + => "#" + (fetch foo) + => 2 + + +File: slib.info, Node: Textual Conversion Packages, Next: Mathematical Packages, Prev: Scheme Syntax Extension Packages, Up: Top + +Textual Conversion Packages +*************************** + +* Menu: + +* Precedence Parsing:: +* Format:: Common-Lisp Format +* Standard Formatted I/O:: Posix printf and scanf +* Programs and Arguments:: +* HTML HTTP and CGI:: Generate pages and serve WWW sites +* Printing Scheme:: Nicely +* Time and Date:: +* Vector Graphics:: +* Schmooz:: Documentation markup for Scheme programs + + +File: slib.info, Node: Precedence Parsing, Next: Format, Prev: Textual Conversion Packages, Up: Textual Conversion Packages + +Precedence Parsing +================== + + `(require 'precedence-parse)' or `(require 'parse)' + +This package implements: + + * a Pratt style precedence parser; + + * a "tokenizer" which congeals tokens according to assigned classes + of constituent characters; + + * procedures giving direct control of parser rulesets; + + * procedures for higher level specification of rulesets. + +* Menu: + +* Precedence Parsing Overview:: +* Ruleset Definition and Use:: +* Token definition:: +* Nud and Led Definition:: +* Grammar Rule Definition:: + + +File: slib.info, Node: Precedence Parsing Overview, Next: Ruleset Definition and Use, Prev: Precedence Parsing, Up: Precedence Parsing + +Precedence Parsing Overview +--------------------------- + +This package offers improvements over previous parsers. + + * Common computer language constructs are concisely specified. + + * Grammars can be changed dynamically. Operators can be assigned + different meanings within a lexical context. + + * Rulesets don't need compilation. Grammars can be changed + incrementally. + + * Operator precedence is specified by integers. + + * All possibilities of bad input are handled (1) and return as much + structure as was parsed when the error occured; The symbol `?' is + substituted for missing input. + +Here are the higher-level syntax types and an example of each. +Precedence considerations are omitted for clarity. See *Note Grammar +Rule Definition:: for full details. + + - Grammar: nofix bye exit + bye + calls the function `exit' with no arguments. + + - Grammar: prefix - negate + - 42 + Calls the function `negate' with the argument `42'. + + - Grammar: infix - difference + x - y + Calls the function `difference' with arguments `x' and `y'. + + - Grammar: nary + sum + x + y + z + Calls the function `sum' with arguments `x', `y', and `y'. + + - Grammar: postfix ! factorial + 5 ! + Calls the function `factorial' with the argument `5'. + + - Grammar: prestfix set set! + set foo bar + Calls the function `set!' with the arguments `foo' and `bar'. + + - Grammar: commentfix /* */ + /* almost any text here */ + Ignores the comment delimited by `/*' and `*/'. + + - Grammar: matchfix { list } + {0, 1, 2} + Calls the function `list' with the arguments `0', `1', and `2'. + + - Grammar: inmatchfix ( funcall ) + f(x, y) + Calls the function `funcall' with the arguments `f', `x', and `y'. + + - Grammar: delim ; + set foo bar; + delimits the extent of the restfix operator `set'. + + ---------- Footnotes ---------- + + (1) How do I know this? I parsed 250kbyte of random input (an e-mail +file) with a non-trivial grammar utilizing all constructs. + + +File: slib.info, Node: Ruleset Definition and Use, Next: Token definition, Prev: Precedence Parsing Overview, Up: Precedence Parsing + +Ruleset Definition and Use +-------------------------- + + - Variable: *syn-defs* + A grammar is built by one or more calls to `prec:define-grammar'. + The rules are appended to *SYN-DEFS*. The value of *SYN-DEFS* is + the grammar suitable for passing as an argument to `prec:parse'. + + - Constant: *syn-ignore-whitespace* + Is a nearly empty grammar with whitespace characters set to group + 0, which means they will not be made into tokens. Most rulesets + will want to start with `*syn-ignore-whitespace*' + +In order to start defining a grammar, either + + (set! *syn-defs* '()) + +or + + (set! *syn-defs* *syn-ignore-whitespace*) + + - Function: prec:define-grammar RULE1 ... + Appends RULE1 ... to *SYN-DEFS*. `prec:define-grammar' is used to + define both the character classes and rules for tokens. + +Once your grammar is defined, save the value of `*syn-defs*' in a +variable (for use when calling `prec:parse'). + + (define my-ruleset *syn-defs*) + + - Function: prec:parse RULESET DELIM + - Function: prec:parse RULESET DELIM PORT + The RULESET argument must be a list of rules as constructed by + `prec:define-grammar' and extracted from *SYN-DEFS*. + + The token DELIM may be a character, symbol, or string. A + character DELIM argument will match only a character token; i.e. a + character for which no token-group is assigned. A symbols or + string will match only a token string; i.e. a token resulting from + a token group. + + `prec:parse' reads a RULESET grammar expression delimited by DELIM + from the given input PORT. `prec:parse' returns the next object + parsable from the given input PORT, updating PORT to point to the + first character past the end of the external representation of the + object. + + If an end of file is encountered in the input before any + characters are found that can begin an object, then an end of file + object is returned. If a delimiter (such as DELIM) is found + before any characters are found that can begin an object, then + `#f' is returned. + + The PORT argument may be omitted, in which case it defaults to the + value returned by `current-input-port'. It is an error to parse + from a closed port. + + +File: slib.info, Node: Token definition, Next: Nud and Led Definition, Prev: Ruleset Definition and Use, Up: Precedence Parsing + +Token definition +---------------- + + - Function: tok:char-group GROUP CHARS CHARS-PROC + The argument CHARS may be a single character, a list of + characters, or a string. Each character in CHARS is treated as + though `tok:char-group' was called with that character alone. + + The argument CHARS-PROC must be a procedure of one argument, a + list of characters. After `tokenize' has finished accumulating + the characters for a token, it calls CHARS-PROC with the list of + characters. The value returned is the token which `tokenize' + returns. + + The argument GROUP may be an exact integer or a procedure of one + character argument. The following discussion concerns the + treatment which the tokenizing routine, `tokenize', will accord to + characters on the basis of their groups. + + When GROUP is a non-zero integer, characters whose group number is + equal to or exactly one less than GROUP will continue to + accumulate. Any other character causes the accumulation to stop + (until a new token is to be read). + + The GROUP of zero is special. These characters are ignored when + parsed pending a token, and stop the accumulation of token + characters when the accumulation has already begun. Whitespace + characters are usually put in group 0. + + If GROUP is a procedure, then, when triggerd by the occurence of + an initial (no accumulation) CHARS character, this procedure will + be repeatedly called with each successive character from the input + stream until the GROUP procedure returns a non-false value. + +The following convenient constants are provided for use with +`tok:char-group'. + + - Constant: tok:decimal-digits + Is the string `"0123456789"'. + + - Constant: tok:upper-case + Is the string consisting of all upper-case letters + ("ABCDEFGHIJKLMNOPQRSTUVWXYZ"). + + - Constant: tok:lower-case + Is the string consisting of all lower-case letters + ("abcdefghijklmnopqrstuvwxyz"). + + - Constant: tok:whitespaces + Is the string consisting of all characters between 0 and 255 for + which `char-whitespace?' returns true. + + +File: slib.info, Node: Nud and Led Definition, Next: Grammar Rule Definition, Prev: Token definition, Up: Precedence Parsing + +Nud and Led Definition +---------------------- + + This section describes advanced features. You can skip this section +on first reading. + +The "Null Denotation" (or "nud") of a token is the procedure and +arguments applying for that token when "Left", an unclaimed parsed +expression is not extant. + +The "Left Denotation" (or "led") of a token is the procedure, +arguments, and lbp applying for that token when there is a "Left", an +unclaimed parsed expression. + +In his paper, + + Pratt, V. R. Top Down Operator Precendence. `SIGACT/SIGPLAN + Symposium on Principles of Programming Languages', Boston, 1973, + pages 41-51 + + the "left binding power" (or "lbp") was an independent property of +tokens. I think this was done in order to allow tokens with NUDs but +not LEDs to also be used as delimiters, which was a problem for +statically defined syntaxes. It turns out that *dynamically binding* +NUDs and LEDs allows them independence. + +For the rule-defining procedures that follow, the variable TK may be a +character, string, or symbol, or a list composed of characters, +strings, and symbols. Each element of TK is treated as though the +procedure were called for each element. + +Character TK arguments will match only character tokens; i.e. +characters for which no token-group is assigned. Symbols and strings +will both match token strings; i.e. tokens resulting from token groups. + + - Function: prec:make-nud TK SOP ARG1 ... + Returns a rule specifying that SOP be called when TK is parsed. + If SOP is a procedure, it is called with TK and ARG1 ... as its + arguments; the resulting value is incorporated into the expression + being built. Otherwise, `(list SOP ARG1 ...)' is incorporated. + +If no NUD has been defined for a token; then if that token is a string, +it is converted to a symbol and returned; if not a string, the token is +returned. + + - Function: prec:make-led TK SOP ARG1 ... + Returns a rule specifying that SOP be called when TK is parsed and + LEFT has an unclaimed parsed expression. If SOP is a procedure, + it is called with LEFT, TK, and ARG1 ... as its arguments; the + resulting value is incorporated into the expression being built. + Otherwise, LEFT is incorporated. + +If no LED has been defined for a token, and LEFT is set, the parser +issues a warning. + + +File: slib.info, Node: Grammar Rule Definition, Prev: Nud and Led Definition, Up: Precedence Parsing + +Grammar Rule Definition +----------------------- + +Here are procedures for defining rules for the syntax types introduced +in *Note Precedence Parsing Overview::. + +For the rule-defining procedures that follow, the variable TK may be a +character, string, or symbol, or a list composed of characters, +strings, and symbols. Each element of TK is treated as though the +procedure were called for each element. + +For procedures prec:delim, ..., prec:prestfix, if the SOP argument is +`#f', then the token which triggered this rule is converted to a symbol +and returned. A false SOP argument to the procedures prec:commentfix, +prec:matchfix, or prec:inmatchfix has a different meaning. + +Character TK arguments will match only character tokens; i.e. +characters for which no token-group is assigned. Symbols and strings +will both match token strings; i.e. tokens resulting from token groups. + + - Function: prec:delim TK + Returns a rule specifying that TK should not be returned from + parsing; i.e. TK's function is purely syntactic. The end-of-file + is always treated as a delimiter. + + - Function: prec:nofix TK SOP + Returns a rule specifying the following actions take place when TK + is parsed: + * If SOP is a procedure, it is called with no arguments; the + resulting value is incorporated into the expression being + built. Otherwise, the list of SOP is incorporated. + + - Function: prec:prefix TK SOP BP RULE1 ... + Returns a rule specifying the following actions take place when TK + is parsed: + * The rules RULE1 ... augment and, in case of conflict, override + rules currently in effect. + + * `prec:parse1' is called with binding-power BP. + + * If SOP is a procedure, it is called with the expression + returned from `prec:parse1'; the resulting value is + incorporated into the expression being built. Otherwise, the + list of SOP and the expression returned from `prec:parse1' is + incorporated. + + * The ruleset in effect before TK was parsed is restored; RULE1 + ... are forgotten. + + - Function: prec:infix TK SOP LBP BP RULE1 ... + Returns a rule declaring the left-binding-precedence of the token + TK is LBP and specifying the following actions take place when TK + is parsed: + * The rules RULE1 ... augment and, in case of conflict, override + rules currently in effect. + + * One expression is parsed with binding-power LBP. If instead a + delimiter is encountered, a warning is issued. + + * If SOP is a procedure, it is applied to the list of LEFT and + the parsed expression; the resulting value is incorporated + into the expression being built. Otherwise, the list of SOP, + the LEFT expression, and the parsed expression is + incorporated. + + * The ruleset in effect before TK was parsed is restored; RULE1 + ... are forgotten. + + - Function: prec:nary TK SOP BP + Returns a rule declaring the left-binding-precedence of the token + TK is BP and specifying the following actions take place when TK + is parsed: + * Expressions are parsed with binding-power BP as far as they + are interleaved with the token TK. + + * If SOP is a procedure, it is applied to the list of LEFT and + the parsed expressions; the resulting value is incorporated + into the expression being built. Otherwise, the list of SOP, + the LEFT expression, and the parsed expressions is + incorporated. + + - Function: prec:postfix TK SOP LBP + Returns a rule declaring the left-binding-precedence of the token + TK is LBP and specifying the following actions take place when TK + is parsed: + * If SOP is a procedure, it is called with the LEFT expression; + the resulting value is incorporated into the expression being + built. Otherwise, the list of SOP and the LEFT expression is + incorporated. + + - Function: prec:prestfix TK SOP BP RULE1 ... + Returns a rule specifying the following actions take place when TK + is parsed: + * The rules RULE1 ... augment and, in case of conflict, override + rules currently in effect. + + * Expressions are parsed with binding-power BP until a + delimiter is reached. + + * If SOP is a procedure, it is applied to the list of parsed + expressions; the resulting value is incorporated into the + expression being built. Otherwise, the list of SOP and the + parsed expressions is incorporated. + + * The ruleset in effect before TK was parsed is restored; RULE1 + ... are forgotten. + + - Function: prec:commentfix TK STP MATCH RULE1 ... + Returns rules specifying the following actions take place when TK + is parsed: + * The rules RULE1 ... augment and, in case of conflict, override + rules currently in effect. + + * Characters are read until and end-of-file or a sequence of + characters is read which matches the *string* MATCH. + + * If STP is a procedure, it is called with the string of all + that was read between the TK and MATCH (exclusive). + + * The ruleset in effect before TK was parsed is restored; RULE1 + ... are forgotten. + + Parsing of commentfix syntax differs from the others in several + ways. It reads directly from input without tokenizing; It calls + STP but does not return its value; nay any value. I added the STP + argument so that comment text could be echoed. + + - Function: prec:matchfix TK SOP SEP MATCH RULE1 ... + Returns a rule specifying the following actions take place when TK + is parsed: + * The rules RULE1 ... augment and, in case of conflict, override + rules currently in effect. + + * A rule declaring the token MATCH a delimiter takes effect. + + * Expressions are parsed with binding-power `0' until the token + MATCH is reached. If the token SEP does not appear between + each pair of expressions parsed, a warning is issued. + + * If SOP is a procedure, it is applied to the list of parsed + expressions; the resulting value is incorporated into the + expression being built. Otherwise, the list of SOP and the + parsed expressions is incorporated. + + * The ruleset in effect before TK was parsed is restored; RULE1 + ... are forgotten. + + - Function: prec:inmatchfix TK SOP SEP MATCH LBP RULE1 ... + Returns a rule declaring the left-binding-precedence of the token + TK is LBP and specifying the following actions take place when TK + is parsed: + * The rules RULE1 ... augment and, in case of conflict, override + rules currently in effect. + + * A rule declaring the token MATCH a delimiter takes effect. + + * Expressions are parsed with binding-power `0' until the token + MATCH is reached. If the token SEP does not appear between + each pair of expressions parsed, a warning is issued. + + * If SOP is a procedure, it is applied to the list of LEFT and + the parsed expressions; the resulting value is incorporated + into the expression being built. Otherwise, the list of SOP, + the LEFT expression, and the parsed expressions is + incorporated. + + * The ruleset in effect before TK was parsed is restored; RULE1 + ... are forgotten. + + +File: slib.info, Node: Format, Next: Standard Formatted I/O, Prev: Precedence Parsing, Up: Textual Conversion Packages + +Format (version 3.0) +==================== + + `(require 'format)' + +* Menu: + +* Format Interface:: +* Format Specification:: + + +File: slib.info, Node: Format Interface, Next: Format Specification, Prev: Format, Up: Format + +Format Interface +---------------- + + - Function: format DESTINATION FORMAT-STRING . ARGUMENTS + An almost complete implementation of Common LISP format description + according to the CL reference book `Common LISP' from Guy L. + Steele, Digital Press. Backward compatible to most of the + available Scheme format implementations. + + Returns `#t', `#f' or a string; has side effect of printing + according to FORMAT-STRING. If DESTINATION is `#t', the output is + to the current output port and `#t' is returned. If DESTINATION + is `#f', a formatted string is returned as the result of the call. + NEW: If DESTINATION is a string, DESTINATION is regarded as the + format string; FORMAT-STRING is then the first argument and the + output is returned as a string. If DESTINATION is a number, the + output is to the current error port if available by the + implementation. Otherwise DESTINATION must be an output port and + `#t' is returned. + + FORMAT-STRING must be a string. In case of a formatting error + format returns `#f' and prints a message on the current output or + error port. Characters are output as if the string were output by + the `display' function with the exception of those prefixed by a + tilde (~). For a detailed description of the FORMAT-STRING syntax + please consult a Common LISP format reference manual. For a test + suite to verify this format implementation load `formatst.scm'. + Please send bug reports to `lutzeb@cs.tu-berlin.de'. + + Note: `format' is not reentrant, i.e. only one `format'-call may + be executed at a time. + + + +File: slib.info, Node: Format Specification, Prev: Format Interface, Up: Format + +Format Specification (Format version 3.0) +----------------------------------------- + + Please consult a Common LISP format reference manual for a detailed +description of the format string syntax. For a demonstration of the +implemented directives see `formatst.scm'. + + This implementation supports directive parameters and modifiers (`:' +and `@' characters). Multiple parameters must be separated by a comma +(`,'). Parameters can be numerical parameters (positive or negative), +character parameters (prefixed by a quote character (`''), variable +parameters (`v'), number of rest arguments parameter (`#'), empty and +default parameters. Directive characters are case independent. The +general form of a directive is: + +DIRECTIVE ::= ~{DIRECTIVE-PARAMETER,}[:][@]DIRECTIVE-CHARACTER + +DIRECTIVE-PARAMETER ::= [ [-|+]{0-9}+ | 'CHARACTER | v | # ] + +Implemented CL Format Control Directives +........................................ + + Documentation syntax: Uppercase characters represent the corresponding +control directive characters. Lowercase characters represent control +directive parameter descriptions. + +`~A' + Any (print as `display' does). + `~@A' + left pad. + + `~MINCOL,COLINC,MINPAD,PADCHARA' + full padding. + +`~S' + S-expression (print as `write' does). + `~@S' + left pad. + + `~MINCOL,COLINC,MINPAD,PADCHARS' + full padding. + +`~D' + Decimal. + `~@D' + print number sign always. + + `~:D' + print comma separated. + + `~MINCOL,PADCHAR,COMMACHARD' + padding. + +`~X' + Hexadecimal. + `~@X' + print number sign always. + + `~:X' + print comma separated. + + `~MINCOL,PADCHAR,COMMACHARX' + padding. + +`~O' + Octal. + `~@O' + print number sign always. + + `~:O' + print comma separated. + + `~MINCOL,PADCHAR,COMMACHARO' + padding. + +`~B' + Binary. + `~@B' + print number sign always. + + `~:B' + print comma separated. + + `~MINCOL,PADCHAR,COMMACHARB' + padding. + +`~NR' + Radix N. + `~N,MINCOL,PADCHAR,COMMACHARR' + padding. + +`~@R' + print a number as a Roman numeral. + +`~:@R' + print a number as an "old fashioned" Roman numeral. + +`~:R' + print a number as an ordinal English number. + +`~:@R' + print a number as a cardinal English number. + +`~P' + Plural. + `~@P' + prints `y' and `ies'. + + `~:P' + as `~P but jumps 1 argument backward.' + + `~:@P' + as `~@P but jumps 1 argument backward.' + +`~C' + Character. + `~@C' + prints a character as the reader can understand it (i.e. `#\' + prefixing). + + `~:C' + prints a character as emacs does (eg. `^C' for ASCII 03). + +`~F' + Fixed-format floating-point (prints a flonum like MMM.NNN). + `~WIDTH,DIGITS,SCALE,OVERFLOWCHAR,PADCHARF' + + `~@F' + If the number is positive a plus sign is printed. + +`~E' + Exponential floating-point (prints a flonum like MMM.NNN`E'EE). + `~WIDTH,DIGITS,EXPONENTDIGITS,SCALE,OVERFLOWCHAR,PADCHAR,EXPONENTCHARE' + + `~@E' + If the number is positive a plus sign is printed. + +`~G' + General floating-point (prints a flonum either fixed or + exponential). + `~WIDTH,DIGITS,EXPONENTDIGITS,SCALE,OVERFLOWCHAR,PADCHAR,EXPONENTCHARG' + + `~@G' + If the number is positive a plus sign is printed. + +`~$' + Dollars floating-point (prints a flonum in fixed with signs + separated). + `~DIGITS,SCALE,WIDTH,PADCHAR$' + + `~@$' + If the number is positive a plus sign is printed. + + `~:@$' + A sign is always printed and appears before the padding. + + `~:$' + The sign appears before the padding. + +`~%' + Newline. + `~N%' + print N newlines. + +`~&' + print newline if not at the beginning of the output line. + `~N&' + prints `~&' and then N-1 newlines. + +`~|' + Page Separator. + `~N|' + print N page separators. + +`~~' + Tilde. + `~N~' + print N tildes. + +`~' + Continuation Line. + `~:' + newline is ignored, white space left. + + `~@' + newline is left, white space ignored. + +`~T' + Tabulation. + `~@T' + relative tabulation. + + `~COLNUM,COLINCT' + full tabulation. + +`~?' + Indirection (expects indirect arguments as a list). + `~@?' + extracts indirect arguments from format arguments. + +`~(STR~)' + Case conversion (converts by `string-downcase'). + `~:(STR~)' + converts by `string-capitalize'. + + `~@(STR~)' + converts by `string-capitalize-first'. + + `~:@(STR~)' + converts by `string-upcase'. + +`~*' + Argument Jumping (jumps 1 argument forward). + `~N*' + jumps N arguments forward. + + `~:*' + jumps 1 argument backward. + + `~N:*' + jumps N arguments backward. + + `~@*' + jumps to the 0th argument. + + `~N@*' + jumps to the Nth argument (beginning from 0) + +`~[STR0~;STR1~;...~;STRN~]' + Conditional Expression (numerical clause conditional). + `~N[' + take argument from N. + + `~@[' + true test conditional. + + `~:[' + if-else-then conditional. + + `~;' + clause separator. + + `~:;' + default clause follows. + +`~{STR~}' + Iteration (args come from the next argument (a list)). + `~N{' + at most N iterations. + + `~:{' + args from next arg (a list of lists). + + `~@{' + args from the rest of arguments. + + `~:@{' + args from the rest args (lists). + +`~^' + Up and out. + `~N^' + aborts if N = 0 + + `~N,M^' + aborts if N = M + + `~N,M,K^' + aborts if N <= M <= K + +Not Implemented CL Format Control Directives +............................................ + +`~:A' + print `#f' as an empty list (see below). + +`~:S' + print `#f' as an empty list (see below). + +`~<~>' + Justification. + +`~:^' + (sorry I don't understand its semantics completely) + +Extended, Replaced and Additional Control Directives +.................................................... + +`~MINCOL,PADCHAR,COMMACHAR,COMMAWIDTHD' + +`~MINCOL,PADCHAR,COMMACHAR,COMMAWIDTHX' + +`~MINCOL,PADCHAR,COMMACHAR,COMMAWIDTHO' + +`~MINCOL,PADCHAR,COMMACHAR,COMMAWIDTHB' + +`~N,MINCOL,PADCHAR,COMMACHAR,COMMAWIDTHR' + COMMAWIDTH is the number of characters between two comma + characters. + +`~I' + print a R4RS complex number as `~F~@Fi' with passed parameters for + `~F'. + +`~Y' + Pretty print formatting of an argument for scheme code lists. + +`~K' + Same as `~?.' + +`~!' + Flushes the output if format DESTINATION is a port. + +`~_' + Print a `#\space' character + `~N_' + print N `#\space' characters. + +`~/' + Print a `#\tab' character + `~N/' + print N `#\tab' characters. + +`~NC' + Takes N as an integer representation for a character. No arguments + are consumed. N is converted to a character by `integer->char'. N + must be a positive decimal number. + +`~:S' + Print out readproof. Prints out internal objects represented as + `#<...>' as strings `"#<...>"' so that the format output can always + be processed by `read'. + +`~:A' + Print out readproof. Prints out internal objects represented as + `#<...>' as strings `"#<...>"' so that the format output can always + be processed by `read'. + +`~Q' + Prints information and a copyright notice on the format + implementation. + `~:Q' + prints format version. + +`~F, ~E, ~G, ~$' + may also print number strings, i.e. passing a number as a string + and format it accordingly. + +Configuration Variables +....................... + + Format has some configuration variables at the beginning of +`format.scm' to suit the systems and users needs. There should be no +modification necessary for the configuration that comes with SLIB. If +modification is desired the variable should be set after the format +code is loaded. Format detects automatically if the running scheme +system implements floating point numbers and complex numbers. + +FORMAT:SYMBOL-CASE-CONV + Symbols are converted by `symbol->string' so the case type of the + printed symbols is implementation dependent. + `format:symbol-case-conv' is a one arg closure which is either + `#f' (no conversion), `string-upcase', `string-downcase' or + `string-capitalize'. (default `#f') + +FORMAT:IOBJ-CASE-CONV + As FORMAT:SYMBOL-CASE-CONV but applies for the representation of + implementation internal objects. (default `#f') + +FORMAT:EXPCH + The character prefixing the exponent value in `~E' printing. + (default `#\E') + +Compatibility With Other Format Implementations +............................................... + +SLIB format 2.x: + See `format.doc'. + +SLIB format 1.4: + Downward compatible except for padding support and `~A', `~S', + `~P', `~X' uppercase printing. SLIB format 1.4 uses C-style + `printf' padding support which is completely replaced by the CL + `format' padding style. + +MIT C-Scheme 7.1: + Downward compatible except for `~', which is not documented + (ignores all characters inside the format string up to a newline + character). (7.1 implements `~a', `~s', ~NEWLINE, `~~', `~%', + numerical and variable parameters and `:/@' modifiers in the CL + sense). + +Elk 1.5/2.0: + Downward compatible except for `~A' and `~S' which print in + uppercase. (Elk implements `~a', `~s', `~~', and `~%' (no + directive parameters or modifiers)). + +Scheme->C 01nov91: + Downward compatible except for an optional destination parameter: + S2C accepts a format call without a destination which returns a + formatted string. This is equivalent to a #f destination in S2C. + (S2C implements `~a', `~s', `~c', `~%', and `~~' (no directive + parameters or modifiers)). + + This implementation of format is solely useful in the SLIB context +because it requires other components provided by SLIB. + + +File: slib.info, Node: Standard Formatted I/O, Next: Programs and Arguments, Prev: Format, Up: Textual Conversion Packages + +Standard Formatted I/O +====================== + +* Menu: + +* Standard Formatted Output:: 'printf +* Standard Formatted Input:: 'scanf + +stdio +----- + + `(require 'stdio)' + + `require's `printf' and `scanf' and additionally defines the symbols: + + - Variable: stdin + Defined to be `(current-input-port)'. + + - Variable: stdout + Defined to be `(current-output-port)'. + + - Variable: stderr + Defined to be `(current-error-port)'. + + +File: slib.info, Node: Standard Formatted Output, Next: Standard Formatted Input, Prev: Standard Formatted I/O, Up: Standard Formatted I/O + +Standard Formatted Output +------------------------- + + `(require 'printf)' + + - Procedure: printf FORMAT ARG1 ... + - Procedure: fprintf PORT FORMAT ARG1 ... + - Procedure: sprintf STR FORMAT ARG1 ... + - Procedure: sprintf #F FORMAT ARG1 ... + - Procedure: sprintf K FORMAT ARG1 ... + Each function converts, formats, and outputs its ARG1 ... + arguments according to the control string FORMAT argument and + returns the number of characters output. + + `printf' sends its output to the port `(current-output-port)'. + `fprintf' sends its output to the port PORT. `sprintf' + `string-set!'s locations of the non-constant string argument STR + to the output characters. + + Two extensions of `sprintf' return new strings. If the first + argument is `#f', then the returned string's length is as many + characters as specified by the FORMAT and data; if the first + argument is a non-negative integer K, then the length of the + returned string is also bounded by K. + + The string FORMAT contains plain characters which are copied to + the output stream, and conversion specifications, each of which + results in fetching zero or more of the arguments ARG1 .... The + results are undefined if there are an insufficient number of + arguments for the format. If FORMAT is exhausted while some of the + ARG1 ... arguments remain unused, the excess ARG1 ... arguments + are ignored. + + The conversion specifications in a format string have the form: + + % [ FLAGS ] [ WIDTH ] [ . PRECISION ] [ TYPE ] CONVERSION + + An output conversion specifications consist of an initial `%' + character followed in sequence by: + + * Zero or more "flag characters" that modify the normal + behavior of the conversion specification. + + `-' + Left-justify the result in the field. Normally the + result is right-justified. + + `+' + For the signed `%d' and `%i' conversions and all inexact + conversions, prefix a plus sign if the value is positive. + + ` ' + For the signed `%d' and `%i' conversions, if the result + doesn't start with a plus or minus sign, prefix it with + a space character instead. Since the `+' flag ensures + that the result includes a sign, this flag is ignored if + both are specified. + + `#' + For inexact conversions, `#' specifies that the result + should always include a decimal point, even if no digits + follow it. For the `%g' and `%G' conversions, this also + forces trailing zeros after the decimal point to be + printed where they would otherwise be elided. + + For the `%o' conversion, force the leading digit to be + `0', as if by increasing the precision. For `%x' or + `%X', prefix a leading `0x' or `0X' (respectively) to + the result. This doesn't do anything useful for the + `%d', `%i', or `%u' conversions. Using this flag + produces output which can be parsed by the `scanf' + functions with the `%i' conversion (*note Standard + Formatted Input::.). + + `0' + Pad the field with zeros instead of spaces. The zeros + are placed after any indication of sign or base. This + flag is ignored if the `-' flag is also specified, or if + a precision is specified for an exact converson. + + * An optional decimal integer specifying the "minimum field + width". If the normal conversion produces fewer characters + than this, the field is padded (with spaces or zeros per the + `0' flag) to the specified width. This is a *minimum* width; + if the normal conversion produces more characters than this, + the field is *not* truncated. + + Alternatively, if the field width is `*', the next argument + in the argument list (before the actual value to be printed) + is used as the field width. The width value must be an + integer. If the value is negative it is as though the `-' + flag is set (see above) and the absolute value is used as the + field width. + + * An optional "precision" to specify the number of digits to be + written for numeric conversions and the maximum field width + for string conversions. The precision is specified by a + period (`.') followed optionally by a decimal integer (which + defaults to zero if omitted). + + Alternatively, if the precision is `.*', the next argument in + the argument list (before the actual value to be printed) is + used as the precision. The value must be an integer, and is + ignored if negative. If you specify `*' for both the field + width and precision, the field width argument precedes the + precision argument. The `.*' precision is an enhancement. C + library versions may not accept this syntax. + + For the `%f', `%e', and `%E' conversions, the precision + specifies how many digits follow the decimal-point character. + The default precision is `6'. If the precision is + explicitly `0', the decimal point character is suppressed. + + For the `%g' and `%G' conversions, the precision specifies how + many significant digits to print. Significant digits are the + first digit before the decimal point, and all the digits + after it. If the precision is `0' or not specified for `%g' + or `%G', it is treated like a value of `1'. If the value + being printed cannot be expressed accurately in the specified + number of digits, the value is rounded to the nearest number + that fits. + + For exact conversions, if a precision is supplied it + specifies the minimum number of digits to appear; leading + zeros are produced if necessary. If a precision is not + supplied, the number is printed with as many digits as + necessary. Converting an exact `0' with an explicit + precision of zero produces no characters. + + * An optional one of `l', `h' or `L', which is ignored for + numeric conversions. It is an error to specify these + modifiers for non-numeric conversions. + + * A character that specifies the conversion to be applied. + +Exact Conversions +................. + + `d', `i' + Print an integer as a signed decimal number. `%d' and `%i' + are synonymous for output, but are different when used with + `scanf' for input (*note Standard Formatted Input::.). + + `o' + Print an integer as an unsigned octal number. + + `u' + Print an integer as an unsigned decimal number. + + `x', `X' + Print an integer as an unsigned hexadecimal number. `%x' + prints using the digits `0123456789abcdef'. `%X' prints + using the digits `0123456789ABCDEF'. + +Inexact Conversions +................... + + `f' + Print a floating-point number in fixed-point notation. + + `e', `E' + Print a floating-point number in exponential notation. `%e' + prints `e' between mantissa and exponont. `%E' prints `E' + between mantissa and exponont. + + `g', `G' + Print a floating-point number in either fixed or exponential | + notation, whichever is more appropriate for its magnitude. + Unless an `#' flag has been supplied trailing zeros after a + decimal point will be stripped off. `%g' prints `e' between + mantissa and exponont. `%G' prints `E' between mantissa and + exponent. + +Other Conversions +................. + + `c' + Print a single character. The `-' flag is the only one which + can be specified. It is an error to specify a precision. + + `s' + Print a string. The `-' flag is the only one which can be + specified. A precision specifies the maximum number of + characters to output; otherwise all characters in the string + are output. + + `a', `A' + Print a scheme expression. The `-' flag left-justifies the + output. The `#' flag specifies that strings and characters + should be quoted as by `write' (which can be read using + `read'); otherwise, output is as `display' prints. A + precision specifies the maximum number of characters to + output; otherwise as many characters as needed are output. + + *Note:* `%a' and `%A' are SLIB extensions. + + `%' + Print a literal `%' character. No argument is consumed. It + is an error to specifiy flags, field width, precision, or + type modifiers with `%%'. + + +File: slib.info, Node: Standard Formatted Input, Prev: Standard Formatted Output, Up: Standard Formatted I/O + +Standard Formatted Input +------------------------ + + `(require 'scanf)' + + - Function: scanf-read-list FORMAT + - Function: scanf-read-list FORMAT PORT + - Function: scanf-read-list FORMAT STRING + + - Macro: scanf FORMAT ARG1 ... + - Macro: fscanf PORT FORMAT ARG1 ... + - Macro: sscanf STR FORMAT ARG1 ... + Each function reads characters, interpreting them according to the + control string FORMAT argument. + + `scanf-read-list' returns a list of the items specified as far as + the input matches FORMAT. `scanf', `fscanf', and `sscanf' return + the number of items successfully matched and stored. `scanf', + `fscanf', and `sscanf' also set the location corresponding to ARG1 + ... using the methods: + + symbol + `set!' + + car expression + `set-car!' + + cdr expression + `set-cdr!' + + vector-ref expression + `vector-set!' + + substring expression + `substring-move-left!' + + The argument to a `substring' expression in ARG1 ... must be a + non-constant string. Characters will be stored starting at the + position specified by the second argument to `substring'. The + number of characters stored will be limited by either the position + specified by the third argument to `substring' or the length of the + matched string, whichever is less. + + The control string, FORMAT, contains conversion specifications and + other characters used to direct interpretation of input sequences. + The control string contains: + + * White-space characters (blanks, tabs, newlines, or formfeeds) + that cause input to be read (and discarded) up to the next + non-white-space character. + + * An ordinary character (not `%') that must match the next + character of the input stream. + + * Conversion specifications, consisting of the character `%', an + optional assignment suppressing character `*', an optional + numerical maximum-field width, an optional `l', `h' or `L' + which is ignored, and a conversion code. + + Unless the specification contains the `n' conversion character + (described below), a conversion specification directs the + conversion of the next input field. The result of a conversion + specification is returned in the position of the corresponding + argument points, unless `*' indicates assignment suppression. + Assignment suppression provides a way to describe an input field + to be skipped. An input field is defined as a string of + characters; it extends to the next inappropriate character or + until the field width, if specified, is exhausted. + + *Note:* This specification of format strings differs from the + `ANSI C' and `POSIX' specifications. In SLIB, white space + before an input field is not skipped unless white space + appears before the conversion specification in the format + string. In order to write format strings which work + identically with `ANSI C' and SLIB, prepend whitespace to all + conversion specifications except `[' and `c'. + + The conversion code indicates the interpretation of the input + field; For a suppressed field, no value is returned. The + following conversion codes are legal: + + `%' + A single % is expected in the input at this point; no value + is returned. + + `d', `D' + A decimal integer is expected. + + `u', `U' + An unsigned decimal integer is expected. + + `o', `O' + An octal integer is expected. + + `x', `X' + A hexadecimal integer is expected. + + `i' + An integer is expected. Returns the value of the next input + item, interpreted according to C conventions; a leading `0' + implies octal, a leading `0x' implies hexadecimal; otherwise, + decimal is assumed. + + `n' + Returns the total number of bytes (including white space) + read by `scanf'. No input is consumed by `%n'. + + `f', `F', `e', `E', `g', `G' + A floating-point number is expected. The input format for + floating-point numbers is an optionally signed string of + digits, possibly containing a radix character `.', followed + by an optional exponent field consisting of an `E' or an `e', + followed by an optional `+', `-', or space, followed by an + integer. + + `c', `C' + WIDTH characters are expected. The normal + skip-over-white-space is suppressed in this case; to read the + next non-space character, use `%1s'. If a field width is + given, a string is returned; up to the indicated number of + characters is read. + + `s', `S' + A character string is expected The input field is terminated + by a white-space character. `scanf' cannot read a null + string. + + `[' + Indicates string data and the normal + skip-over-leading-white-space is suppressed. The left + bracket is followed by a set of characters, called the + scanset, and a right bracket; the input field is the maximal + sequence of input characters consisting entirely of + characters in the scanset. `^', when it appears as the first + character in the scanset, serves as a complement operator and + redefines the scanset as the set of all characters not + contained in the remainder of the scanset string. + Construction of the scanset follows certain conventions. A + range of characters may be represented by the construct + first-last, enabling `[0123456789]' to be expressed `[0-9]'. + Using this convention, first must be lexically less than or + equal to last; otherwise, the dash stands for itself. The + dash also stands for itself when it is the first or the last + character in the scanset. To include the right square + bracket as an element of the scanset, it must appear as the + first character (possibly preceded by a `^') of the scanset, + in which case it will not be interpreted syntactically as the + closing bracket. At least one character must match for this + conversion to succeed. + + The `scanf' functions terminate their conversions at end-of-file, + at the end of the control string, or when an input character + conflicts with the control string. In the latter case, the + offending character is left unread in the input stream. + + +File: slib.info, Node: Programs and Arguments, Next: HTML HTTP and CGI, Prev: Standard Formatted I/O, Up: Textual Conversion Packages + +Program and Arguments +===================== + +* Menu: + +* Getopt:: Command Line option parsing +* Command Line:: A command line reader for Scheme shells +* Parameter lists:: 'parameters +* Getopt Parameter lists:: 'getopt-parameters +* Filenames:: 'glob or 'filename +* Batch:: 'batch + + +File: slib.info, Node: Getopt, Next: Command Line, Prev: Programs and Arguments, Up: Programs and Arguments + +Getopt +------ + + `(require 'getopt)' + + This routine implements Posix command line argument parsing. Notice +that returning values through global variables means that `getopt' is +*not* reentrant. + + - Variable: *optind* + Is the index of the current element of the command line. It is + initially one. In order to parse a new command line or reparse an + old one, *OPTING* must be reset. + + - Variable: *optarg* + Is set by getopt to the (string) option-argument of the current + option. + + - Procedure: getopt ARGC ARGV OPTSTRING + Returns the next option letter in ARGV (starting from `(vector-ref + argv *optind*)') that matches a letter in OPTSTRING. ARGV is a + vector or list of strings, the 0th of which getopt usually + ignores. ARGC is the argument count, usually the length of ARGV. + OPTSTRING is a string of recognized option characters; if a + character is followed by a colon, the option takes an argument + which may be immediately following it in the string or in the next + element of ARGV. + + *OPTIND* is the index of the next element of the ARGV vector to be + processed. It is initialized to 1 by `getopt.scm', and `getopt' + updates it when it finishes with each element of ARGV. + + `getopt' returns the next option character from ARGV that matches + a character in OPTSTRING, if there is one that matches. If the + option takes an argument, `getopt' sets the variable *OPTARG* to + the option-argument as follows: + + * If the option was the last character in the string pointed to + by an element of ARGV, then *OPTARG* contains the next + element of ARGV, and *OPTIND* is incremented by 2. If the + resulting value of *OPTIND* is greater than or equal to ARGC, + this indicates a missing option argument, and `getopt' + returns an error indication. + + * Otherwise, *OPTARG* is set to the string following the option + character in that element of ARGV, and *OPTIND* is + incremented by 1. + + If, when `getopt' is called, the string `(vector-ref argv + *optind*)' either does not begin with the character `#\-' or is + just `"-"', `getopt' returns `#f' without changing *OPTIND*. If + `(vector-ref argv *optind*)' is the string `"--"', `getopt' + returns `#f' after incrementing *OPTIND*. + + If `getopt' encounters an option character that is not contained in + OPTSTRING, it returns the question-mark `#\?' character. If it + detects a missing option argument, it returns the colon character + `#\:' if the first character of OPTSTRING was a colon, or a + question-mark character otherwise. In either case, `getopt' sets + the variable GETOPT:OPT to the option character that caused the + error. + + The special option `"--"' can be used to delimit the end of the + options; `#f' is returned, and `"--"' is skipped. + + RETURN VALUE + + `getopt' returns the next option character specified on the command + line. A colon `#\:' is returned if `getopt' detects a missing + argument and the first character of OPTSTRING was a colon `#\:'. + + A question-mark `#\?' is returned if `getopt' encounters an option + character not in OPTSTRING or detects a missing argument and the + first character of OPTSTRING was not a colon `#\:'. + + Otherwise, `getopt' returns `#f' when all command line options + have been parsed. + + Example: + #! /usr/local/bin/scm + ;;;This code is SCM specific. + (define argv (program-arguments)) + (require 'getopt) + + (define opts ":a:b:cd") + (let loop ((opt (getopt (length argv) argv opts))) + (case opt + ((#\a) (print "option a: " *optarg*)) + ((#\b) (print "option b: " *optarg*)) + ((#\c) (print "option c")) + ((#\d) (print "option d")) + ((#\?) (print "error" getopt:opt)) + ((#\:) (print "missing arg" getopt:opt)) + ((#f) (if (< *optind* (length argv)) + (print "argv[" *optind* "]=" + (list-ref argv *optind*))) + (set! *optind* (+ *optind* 1)))) + (if (< *optind* (length argv)) + (loop (getopt (length argv) argv opts)))) + + (slib:exit) + +Getopt- +------- + + - Function: getopt- ARGC ARGV OPTSTRING + The procedure `getopt--' is an extended version of `getopt' which + parses "long option names" of the form `--hold-the-onions' and + `--verbosity-level=extreme'. `Getopt--' behaves as `getopt' + except for non-empty options beginning with `--'. + + Options beginning with `--' are returned as strings rather than + characters. If a value is assigned (using `=') to a long option, + `*optarg*' is set to the value. The `=' and value are not + returned as part of the option string. + + No information is passed to `getopt--' concerning which long + options should be accepted or whether such options can take + arguments. If a long option did not have an argument, `*optarg' + will be set to `#f'. The caller is responsible for detecting and + reporting errors. + + (define opts ":-:b:") + (define argc 5) + (define argv '("foo" "-b9" "--f1" "--2=" "--g3=35234.342" "--")) + (define *optind* 1) + (define *optarg* #f) + (require 'qp) + (do ((i 5 (+ -1 i))) + ((zero? i)) + (define opt (getopt-- argc argv opts)) + (print *optind* opt *optarg*))) + -| + 2 #\b "9" + 3 "f1" #f + 4 "2" "" + 5 "g3" "35234.342" + 5 #f "35234.342" + + +File: slib.info, Node: Command Line, Next: Parameter lists, Prev: Getopt, Up: Programs and Arguments + +Command Line +------------ + + `(require 'read-command)' + + - Function: read-command PORT + - Function: read-command + `read-command' converts a "command line" into a list of strings + suitable for parsing by `getopt'. The syntax of command lines + supported resembles that of popular "shell"s. `read-command' + updates PORT to point to the first character past the command + delimiter. + + If an end of file is encountered in the input before any + characters are found that can begin an object or comment, then an + end of file object is returned. + + The PORT argument may be omitted, in which case it defaults to the + value returned by `current-input-port'. + + The fields into which the command line is split are delimited by + whitespace as defined by `char-whitespace?'. The end of a command + is delimited by end-of-file or unescaped semicolon (<;>) or + . Any character can be literally included in a field by + escaping it with a backslach (<\>). + + The initial character and types of fields recognized are: + `\' + The next character has is taken literally and not interpreted + as a field delimiter. If <\> is the last character before a + , that is just ignored. Processing + continues from the characters after the as though + the backslash and were not there. + + `"' + The characters up to the next unescaped <"> are taken + literally, according to [R4RS] rules for literal strings + (*note Strings: (r4rs)Strings.). + + `(', `%'' + One scheme expression is `read' starting with this character. + The `read' expression is evaluated, converted to a string + (using `display'), and replaces the expression in the returned + field. + + `;' + Semicolon delimits a command. Using semicolons more than one + command can appear on a line. Escaped semicolons and + semicolons inside strings do not delimit commands. + + The comment field differs from the previous fields in that it must + be the first character of a command or appear after whitespace in + order to be recognized. <#> can be part of fields if these + conditions are not met. For instance, `ab#c' is just the field + ab#c. + + `#' + Introduces a comment. The comment continues to the end of + the line on which the semicolon appears. Comments are + treated as whitespace by `read-dommand-line' and backslashes + before s in comments are also ignored. + + - Function: read-options-file FILENAME + `read-options-file' converts an "options file" into a list of + strings suitable for parsing by `getopt'. The syntax of options + files is the same as the syntax for command lines, except that + s do not terminate reading (only <;> or end of file). + + If an end of file is encountered before any characters are found + that can begin an object or comment, then an end of file object is + returned. + + +File: slib.info, Node: Parameter lists, Next: Getopt Parameter lists, Prev: Command Line, Up: Programs and Arguments + +Parameter lists +--------------- + + `(require 'parameters)' + +Arguments to procedures in scheme are distinguished from each other by +their position in the procedure call. This can be confusing when a +procedure takes many arguments, many of which are not often used. + +A "parameter-list" is a way of passing named information to a +procedure. Procedures are also defined to set unused parameters to +default values, check parameters, and combine parameter lists. + +A PARAMETER has the form `(parameter-name value1 ...)'. This format +allows for more than one value per parameter-name. + +A PARAMETER-LIST is a list of PARAMETERs, each with a different +PARAMETER-NAME. + + - Function: make-parameter-list PARAMETER-NAMES + Returns an empty parameter-list with slots for PARAMETER-NAMES. + + - Function: parameter-list-ref PARAMETER-LIST PARAMETER-NAME + PARAMETER-NAME must name a valid slot of PARAMETER-LIST. + `parameter-list-ref' returns the value of parameter PARAMETER-NAME + of PARAMETER-LIST. + + - Procedure: adjoin-parameters! PARAMETER-LIST PARAMETER1 ... + Returns PARAMETER-LIST with PARAMETER1 ... merged in. + + - Procedure: parameter-list-expand EXPANDERS PARAMETER-LIST + EXPANDERS is a list of procedures whose order matches the order of + the PARAMETER-NAMEs in the call to `make-parameter-list' which + created PARAMETER-LIST. For each non-false element of EXPANDERS + that procedure is mapped over the corresponding parameter value + and the returned parameter lists are merged into PARAMETER-LIST. + + This process is repeated until PARAMETER-LIST stops growing. The + value returned from `parameter-list-expand' is unspecified. + + - Function: fill-empty-parameters DEFAULTERS PARAMETER-LIST + DEFAULTERS is a list of procedures whose order matches the order + of the PARAMETER-NAMEs in the call to `make-parameter-list' which + created PARAMETER-LIST. `fill-empty-parameters' returns a new + parameter-list with each empty parameter replaced with the list + returned by calling the corresponding DEFAULTER with + PARAMETER-LIST as its argument. + + - Function: check-parameters CHECKS PARAMETER-LIST + CHECKS is a list of procedures whose order matches the order of + the PARAMETER-NAMEs in the call to `make-parameter-list' which + created PARAMETER-LIST. + + `check-parameters' returns PARAMETER-LIST if each CHECK of the + corresponding PARAMETER-LIST returns non-false. If some CHECK + returns `#f' an error is signaled. + +In the following procedures ARITIES is a list of symbols. The elements +of `arities' can be: + +`single' + Requires a single parameter. + +`optional' + A single parameter or no parameter is acceptable. + +`boolean' + A single boolean parameter or zero parameters is acceptable. + +`nary' + Any number of parameters are acceptable. + +`nary1' + One or more of parameters are acceptable. + + - Function: parameter-list->arglist POSITIONS ARITIES TYPES + PARAMETER-LIST + Returns PARAMETER-LIST converted to an argument list. Parameters + of ARITY type `single' and `boolean' are converted to the single + value associated with them. The other ARITY types are converted + to lists of the value(s) of type TYPES. + + POSITIONS is a list of positive integers whose order matches the + order of the PARAMETER-NAMEs in the call to `make-parameter-list' + which created PARAMETER-LIST. The integers specify in which + argument position the corresponding parameter should appear. + + +File: slib.info, Node: Getopt Parameter lists, Next: Filenames, Prev: Parameter lists, Up: Programs and Arguments + +Getopt Parameter lists +---------------------- + + `(require 'getopt-parameters)' + + - Function: getopt->parameter-list ARGC ARGV OPTNAMES ARITIES TYPES + ALIASES + Returns ARGV converted to a parameter-list. OPTNAMES are the + parameter-names. ALIASES is a list of lists of strings and + elements of OPTNAMES. Each of these strings which have length of + 1 will be treated as a single <-> option by `getopt'. Longer + strings will be treated as long-named options (*note getopt-: + Getopt.). + + - Function: getopt->arglist ARGC ARGV OPTNAMES POSITIONS ARITIES TYPES + DEFAULTERS CHECKS ALIASES + Like `getopt->parameter-list', but converts ARGV to an + argument-list as specified by OPTNAMES, POSITIONS, ARITIES, TYPES, + DEFAULTERS, CHECKS, and ALIASES. + +These `getopt' functions can be used with SLIB relational databases. +For an example, *Note make-command-server: Database Utilities. + +If errors are encountered while processing options, directions for using +the options are printed to `current-error-port'. + + (begin + (set! *optind* 1) + (getopt->parameter-list + 2 + '("cmd" "-?") + '(flag number symbols symbols string flag2 flag3 num2 num3) + '(boolean optional nary1 nary single boolean boolean nary nary) + '(boolean integer symbol symbol string boolean boolean integer integer) + '(("flag" flag) + ("f" flag) + ("Flag" flag2) + ("B" flag3) + ("optional" number) + ("o" number) + ("nary1" symbols) + ("N" symbols) + ("nary" symbols) + ("n" symbols) + ("single" string) + ("s" string) + ("a" num2) + ("Abs" num3)))) + -| + Usage: cmd [OPTION ARGUMENT ...] ... + + -f, --flag + -o, --optional= + -n, --nary= ... + -N, --nary1= ... + -s, --single= + --Flag + -B + -a ... + --Abs= ... + + ERROR: getopt->parameter-list "unrecognized option" "-?" + + +File: slib.info, Node: Filenames, Next: Batch, Prev: Getopt Parameter lists, Up: Programs and Arguments + +Filenames +--------- + + `(require 'filename)' or `(require 'glob)' + + - Function: filename:match?? PATTERN + - Function: filename:match-ci?? PATTERN + Returns a predicate which returns a non-false value if its string + argument matches (the string) PATTERN, false otherwise. Filename + matching is like "glob" expansion described the bash manpage, + except that names beginning with `.' are matched and `/' + characters are not treated specially. + + These functions interpret the following characters specially in + PATTERN strings: + `*' + Matches any string, including the null string. + + `?' + Matches any single character. + + `[...]' + Matches any one of the enclosed characters. A pair of + characters separated by a minus sign (-) denotes a range; any + character lexically between those two characters, inclusive, + is matched. If the first character following the `[' is a + `!' or a `^' then any character not enclosed is matched. A + `-' or `]' may be matched by including it as the first or + last character in the set. + + + - Function: filename:substitute?? PATTERN TEMPLATE + - Function: filename:substitute-ci?? PATTERN TEMPLATE + Returns a function transforming a single string argument according + to glob patterns PATTERN and TEMPLATE. PATTERN and TEMPLATE must + have the same number of wildcard specifications, which need not be + identical. PATTERN and TEMPLATE may have a different number of + literal sections. If an argument to the function matches PATTERN + in the sense of `filename:match??' then it returns a copy of + TEMPLATE in which each wildcard specification is replaced by the + part of the argument matched by the corresponding wildcard + specification in PATTERN. A `*' wildcard matches the longest + leftmost string possible. If the argument does not match PATTERN + then false is returned. + + TEMPLATE may be a function accepting the same number of string + arguments as there are wildcard specifications in PATTERN. In the + case of a match the result of applying TEMPLATE to a list of the + substrings matched by wildcard specifications will be returned, + otherwise TEMPLATE will not be called and `#f' will be returned. + + ((filename:substitute?? "scm_[0-9]*.html" "scm5c4_??.htm") + "scm_10.html") + => "scm5c4_10.htm" + ((filename:substitute?? "??" "beg?mid?end") "AZ") + => "begAmidZend" + ((filename:substitute?? "*na*" "?NA?") "banana") + => "banaNA" + ((filename:substitute?? "?*?" (lambda (s1 s2 s3) (string-append s3 s1))) "ABZ") + => "ZA" + + - Function: replace-suffix STR OLD NEW + STR can be a string or a list of strings. Returns a new string + (or strings) similar to `str' but with the suffix string OLD + removed and the suffix string NEW appended. If the end of STR + does not match OLD, an error is signaled. + + (replace-suffix "/usr/local/lib/slib/batch.scm" ".scm" ".c") + => "/usr/local/lib/slib/batch.c" + + +File: slib.info, Node: Batch, Prev: Filenames, Up: Programs and Arguments + +Batch +----- + + `(require 'batch)' + +The batch procedures provide a way to write and execute portable scripts +for a variety of operating systems. Each `batch:' procedure takes as +its first argument a parameter-list (*note Parameter lists::.). This +parameter-list argument PARMS contains named associations. Batch +currently uses 2 of these: + +`batch-port' + The port on which to write lines of the batch file. + +`batch-dialect' + The syntax of batch file to generate. Currently supported are: + * unix + + * dos + + * vms + + * amigados + + * system + + * *unknown* + +`batch.scm' uses 2 enhanced relational tables (*note Database +Utilities::.) to store information linking the names of +`operating-system's to `batch-dialect'es. + + - Function: batch:initialize! DATABASE + Defines `operating-system' and `batch-dialect' tables and adds the + domain `operating-system' to the enhanced relational database + DATABASE. + + - Variable: batch:platform + Is batch's best guess as to which operating-system it is running + under. `batch:platform' is set to `(software-type)' (*note + Configuration::.) unless `(software-type)' is `unix', in which + case finer distinctions are made. + + - Function: batch:call-with-output-script PARMS FILE PROC + PROC should be a procedure of one argument. If FILE is an + output-port, `batch:call-with-output-script' writes an appropriate + header to FILE and then calls PROC with FILE as the only argument. + If FILE is a string, `batch:call-with-output-script' opens a + output-file of name FILE, writes an appropriate header to FILE, + and then calls PROC with the newly opened port as the only + argument. Otherwise, `batch:call-with-output-script' acts as if + it was called with the result of `(current-output-port)' as its + third argument. + | +The rest of the `batch:' procedures write (or execute if +`batch-dialect' is `system') commands to the batch port which has been +added to PARMS or `(copy-tree PARMS)' by the code: + + (adjoin-parameters! PARMS (list 'batch-port PORT)) + + - Function: batch:command PARMS STRING1 STRING2 ... | + Calls `batch:try-command' (below) with arguments, but signals an | + error if `batch:try-command' returns `#f'. | + +These functions return a non-false value if the command was successfully +translated into the batch dialect and `#f' if not. In the case of the +`system' dialect, the value is non-false if the operation suceeded. + + - Function: batch:try-command PARMS STRING1 STRING2 ... | + Writes a command to the `batch-port' in PARMS which executes the + program named STRING1 with arguments STRING2 .... + + - Function: batch:try-chopped-command PARMS ARG1 ARG2 ... LIST | + breaks the last argument LIST into chunks small enough so that the | + command: | + | + ARG1 ARG2 ... CHUNK | + | + fits withing the platform's maximum command-line length. | + | + `batch:try-chopped-command' calls `batch:try-command' with the | + command and returns non-false only if the commands all fit and | + `batch:try-command' of each command line returned non-false. | + | + - Function: batch:run-script PARMS STRING1 STRING2 ... + Writes a command to the `batch-port' in PARMS which executes the + batch script named STRING1 with arguments STRING2 .... + + *Note:* `batch:run-script' and `batch:try-command' are not the | + same for some operating systems (VMS). | + + - Function: batch:comment PARMS LINE1 ... + Writes comment lines LINE1 ... to the `batch-port' in PARMS. + + - Function: batch:lines->file PARMS FILE LINE1 ... + Writes commands to the `batch-port' in PARMS which create a file + named FILE with contents LINE1 .... + + - Function: batch:delete-file PARMS FILE + Writes a command to the `batch-port' in PARMS which deletes the + file named FILE. + + - Function: batch:rename-file PARMS OLD-NAME NEW-NAME + Writes a command to the `batch-port' in PARMS which renames the + file OLD-NAME to NEW-NAME. + +In addition, batch provides some small utilities very useful for writing +scripts: + + - Function: truncate-up-to PATH CHAR + - Function: truncate-up-to PATH STRING + - Function: truncate-up-to PATH CHARLIST + PATH can be a string or a list of strings. Returns PATH sans any + prefixes ending with a character of the second argument. This can + be used to derive a filename moved locally from elsewhere. + + (truncate-up-to "/usr/local/lib/slib/batch.scm" "/") + => "batch.scm" + + - Function: string-join JOINER STRING1 ... + Returns a new string consisting of all the strings STRING1 ... in + order appended together with the string JOINER between each + adjacent pair. + + - Function: must-be-first LIST1 LIST2 + Returns a new list consisting of the elements of LIST2 ordered so + that if some elements of LIST1 are `equal?' to elements of LIST2, + then those elements will appear first and in the order of LIST1. + + - Function: must-be-last LIST1 LIST2 + Returns a new list consisting of the elements of LIST1 ordered so + that if some elements of LIST2 are `equal?' to elements of LIST1, + then those elements will appear last and in the order of LIST2. + + - Function: os->batch-dialect OSNAME + Returns its best guess for the `batch-dialect' to be used for the + operating-system named OSNAME. `os->batch-dialect' uses the + tables added to DATABASE by `batch:initialize!'. + +Here is an example of the use of most of batch's procedures: + + (require 'database-utilities) + (require 'parameters) + (require 'batch) + (require 'glob) + + (define batch (create-database #f 'alist-table)) + (batch:initialize! batch) + + (define my-parameters + (list (list 'batch-dialect (os->batch-dialect batch:platform)) + (list 'platform batch:platform) + (list 'batch-port (current-output-port)))) ;gets filled in later + + (batch:call-with-output-script + my-parameters + "my-batch" + (lambda (batch-port) + (adjoin-parameters! my-parameters (list 'batch-port batch-port)) + (and + (batch:comment my-parameters + "================ Write file with C program.") + (batch:rename-file my-parameters "hello.c" "hello.c~") + (batch:lines->file my-parameters "hello.c" + "#include " + "int main(int argc, char **argv)" + "{" + " printf(\"hello world\\n\");" + " return 0;" + "}" ) + (batch:command my-parameters "cc" "-c" "hello.c") | + (batch:command my-parameters "cc" "-o" "hello" | + (replace-suffix "hello.c" ".c" ".o")) + (batch:command my-parameters "hello") | + (batch:delete-file my-parameters "hello") + (batch:delete-file my-parameters "hello.c") + (batch:delete-file my-parameters "hello.o") + (batch:delete-file my-parameters "my-batch") + ))) + +Produces the file `my-batch': + + #!/bin/sh + # "my-batch" script created by SLIB/batch Sun Oct 31 18:24:10 1999 | + # ================ Write file with C program. + mv -f hello.c hello.c~ + rm -f hello.c + echo '#include '>>hello.c + echo 'int main(int argc, char **argv)'>>hello.c + echo '{'>>hello.c + echo ' printf("hello world\n");'>>hello.c + echo ' return 0;'>>hello.c + echo '}'>>hello.c + cc -c hello.c + cc -o hello hello.o + hello + rm -f hello + rm -f hello.c + rm -f hello.o + rm -f my-batch + +When run, `my-batch' prints: + + bash$ my-batch + mv: hello.c: No such file or directory + hello world + + +File: slib.info, Node: HTML HTTP and CGI, Next: Printing Scheme, Prev: Programs and Arguments, Up: Textual Conversion Packages + +HTML Forms +========== + + `(require 'html-form)' + + - Variable: *html:output-port* + Procedure names starting with `html:' send their output to the + port *HTML:OUTPUT-PORT*. *HTML:OUTPUT-PORT* is initially the + current output port. + + - Function: make-atval TXT + Returns a string with character substitutions appropriate to send + TXT as an "attribute-value". + + - Function: make-plain TXT + Returns a string with character substitutions appropriate to send + TXT as an "plain-text". + + - Function: html:start-page TITLE BACKLINK TAGS ... + - Function: html:start-page TITLE BACKLINK + - Function: html:start-page TITLE + Outputs headers for an HTML page named TITLE. If string arguments + BACKLINK ... are supplied they are printed verbatim within the + section. + + - Function: html:end-page + Outputs HTML codes to end a page. + + - Function: html:pre LINE1 LINE ... + Writes (using `html:printf') the strings LINE1, LINES as + "PRE"formmated plain text (rendered in fixed-width font). + Newlines are inserted between LINE1, LINES. HTML tags (`') + within LINES will be visible verbatim. + + - Function: html:comment LINE1 LINE ... + Writes (using `html:printf') the strings LINE1 as HTML comments. + +HTML Tables +=========== + + - Function: html:start-table CAPTION + + - Function: html:end-table + + - Function: html:heading COLUMNS + Outputs a heading row for the currently-started table. + + - Function: html:href-heading COLUMNS URLS + Outputs a heading row with column-names COLUMNS linked to URLs + URLS. + + - Function: make-row-converter K FOREIGNS + The positive integer K is the primary-key-limit (number of + primary-keys) of the table. FOREIGNS is a list of the filenames of + foreign-key field pages and #f for non foreign-key fields. + + `make-row-converter' returns a procedure taking a row for its + single argument. This returned procedure prints the table row to + *HTML:OUTPUT-PORT*. + + - Function: table-name->filename TABLE-NAME + Returns the symbol TABLE-NAME converted to a filename. + + - Function: table->html CAPTION DB TABLE-NAME MATCH-KEY1 ... + Writes HTML for DB table TABLE-NAME to *HTML:OUTPUT-PORT*. + + The optional MATCH-KEY1 ... arguments restrict actions to a subset + of the table. *Note match-key: Table Operations. + + - Function: table->page DB TABLE-NAME INDEX-FILENAME + Writes a complete HTML page to *HTML:OUTPUT-PORT*. The string + INDEX-FILENAME names the page which refers to this one. + + - Function: catalog->html DB CAPTION + Writes HTML for the catalog table of DB to *HTML:OUTPUT-PORT*. + + - Function: catalog->page DB CAPTION + Writes a complete HTML page for the catalog of DB to + *HTML:OUTPUT-PORT*. + +HTML Forms +========== + + - Function: html:start-form METHOD ACTION + The symbol METHOD is either `get', `head', `post', `put', or + `delete'. `html:start-form' prints the header for an HTML "form". + + - Function: html:end-form PNAME SUBMIT-LABEL + `html:end-form' prints the footer for an HTML "form". The string + SUBMIT-LABEL appears on the button which submits the form. + + - Function: command->html RDB COMMAND-TABLE COMMAND METHOD ACTION + The symbol COMMAND-TABLE names a command table in the RDB + relational database. + + `command->html' writes an HTML-2.0 "form" for command COMMAND to + the current-output-port. The `SUBMIT' button, which is labeled + COMMAND, invokes the URI ACTION with method METHOD with a hidden + attribute `*command*' bound to the command symbol submitted. + + An action may invoke a CGI script + (`http://www.my-site.edu/cgi-bin/search.cgi') or HTTP daemon + (`http://www.my-site.edu:8001'). + + This example demonstrates how to create a HTML-form for the `build' + command. + + (require (in-vicinity (implementation-vicinity) "build.scm")) + (call-with-output-file "buildscm.html" + (lambda (port) + (fluid-let ((*html:output-port* port)) + (html:start-page 'commands) + (command->html + build '*commands* 'build 'post + (or "/cgi-bin/build.cgi" + "http://localhost:8081/buildscm")) + html:end-page))) + +HTTP and CGI service +==================== + + `(require 'html-form)' + + - Function: cgi:serve-command RDB COMMAND-TABLE + Reads a `"POST"' or `"GET"' query from `(current-input-port)' and + executes the encoded command from COMMAND-TABLE in + relational-database RDB. + + This example puts up a plain-text page in response to a CGI query. + + (display "Content-Type: text/plain") (newline) (newline) + (require 'html-form) + (load (in-vicinity (implementation-vicinity) "build.scm")) + (cgi:serve-command build '*commands*) + + - Function: serve-urlencoded-command RDB COMMAND-TABLE URLENCODED + Reads attribute-value pairs from URLENCODED, converts them to + parameters and invokes the RDB command named by the parameter + `*command*'. + + - Function: http:serve-query INPUT-PORT OUTPUT-PORT SERVE-PROC + reads the "query-string" from INPUT-PORT. If this is a valid + `"POST"' or `"GET"' query, then `http:serve-query' calls + SERVE-PROC with two arguments, the query-string and the + header-alist. + + Otherwise, `http:serve-query' replies (to OUTPUT-PORT) with + appropriate HTML describing the problem. + + This example services HTTP queries from port 8081: + + (define socket (make-stream-socket AF_INET 0)) + (socket:bind socket 8081) + (socket:listen socket 10) + (dynamic-wind + (lambda () #f) + (lambda () + (do ((port (socket:accept socket) + (socket:accept socket))) + (#f) + (dynamic-wind + (lambda () #f) + (lambda () + (fluid-let ((*html:output-port* port)) + (http:serve-query + port port + (lambda (query-string header) + (http:send-header + '(("Content-Type" . "text/plain"))) + (with-output-to-port port + (lambda () + (serve-urlencoded-command + build '*commands* query-string))))))) + (lambda () (close-port port))))) + (lambda () (close-port socket))) + + - Function: http:read-request-line PORT + Reads the first non-blank line from PORT and, if successful, + returns a list of three itmes from the request-line: + + 0. Method + + Either one of the symbols `options', `get', `head', `post', + `put', `delete', or `trace'; Or a string. + + 1. Request-URI + + A string. At the minimum, it will be the string `"/"'. + + 2. HTTP-Version + + A string. For example, `HTTP/1.0'. + + - Function: cgi:read-query-string + Reads the "query-string" from `(current-input-port)'. + `cgi:read-query-string' reads a `"POST"' or `"GET"' queries, + depending on the value of `(getenv "REQUEST_METHOD")'. + + +File: slib.info, Node: Printing Scheme, Next: Time and Date, Prev: HTML HTTP and CGI, Up: Textual Conversion Packages + +Printing Scheme +=============== + +* Menu: + +* Generic-Write:: 'generic-write +* Object-To-String:: 'object->string +* Pretty-Print:: 'pretty-print, 'pprint-file + + +File: slib.info, Node: Generic-Write, Next: Object-To-String, Prev: Printing Scheme, Up: Printing Scheme + +Generic-Write +------------- + + `(require 'generic-write)' + + `generic-write' is a procedure that transforms a Scheme data value +(or Scheme program expression) into its textual representation and +prints it. The interface to the procedure is sufficiently general to +easily implement other useful formatting procedures such as pretty +printing, output to a string and truncated output. + + - Procedure: generic-write OBJ DISPLAY? WIDTH OUTPUT + OBJ + Scheme data value to transform. + + DISPLAY? + Boolean, controls whether characters and strings are quoted. + + WIDTH + Extended boolean, selects format: + #f + single line format + + integer > 0 + pretty-print (value = max nb of chars per line) + + OUTPUT + Procedure of 1 argument of string type, called repeatedly with + successive substrings of the textual representation. This + procedure can return `#f' to stop the transformation. + + The value returned by `generic-write' is undefined. + + Examples: + (write obj) == (generic-write obj #f #f DISPLAY-STRING) + (display obj) == (generic-write obj #t #f DISPLAY-STRING) + + where + DISPLAY-STRING == + (lambda (s) (for-each write-char (string->list s)) #t) + + +File: slib.info, Node: Object-To-String, Next: Pretty-Print, Prev: Generic-Write, Up: Printing Scheme + +Object-To-String +---------------- + + `(require 'object->string)' + + - Function: object->string OBJ + Returns the textual representation of OBJ as a string. + + - Function: object->limited-string OBJ LIMIT + Returns the textual representation of OBJ as a string of length at + most LIMIT. + + +File: slib.info, Node: Pretty-Print, Prev: Object-To-String, Up: Printing Scheme + +Pretty-Print +------------ + + `(require 'pretty-print)' + + - Procedure: pretty-print OBJ + - Procedure: pretty-print OBJ PORT + `pretty-print's OBJ on PORT. If PORT is not specified, + `current-output-port' is used. + + Example: + (pretty-print '((1 2 3 4 5) (6 7 8 9 10) (11 12 13 14 15) + (16 17 18 19 20) (21 22 23 24 25))) + -| ((1 2 3 4 5) + -| (6 7 8 9 10) + -| (11 12 13 14 15) + -| (16 17 18 19 20) + -| (21 22 23 24 25)) + + `(require 'pprint-file)' + + - Procedure: pprint-file INFILE + - Procedure: pprint-file INFILE OUTFILE + Pretty-prints all the code in INFILE. If OUTFILE is specified, + the output goes to OUTFILE, otherwise it goes to + `(current-output-port)'. + + - Function: pprint-filter-file INFILE PROC OUTFILE + - Function: pprint-filter-file INFILE PROC + INFILE is a port or a string naming an existing file. Scheme + source code expressions and definitions are read from the port (or + file) and PROC is applied to them sequentially. + + OUTFILE is a port or a string. If no OUTFILE is specified then + `current-output-port' is assumed. These expanded expressions are + then `pretty-print'ed to this port. + + Whitepsace and comments (introduced by `;') which are not part of + scheme expressions are reproduced in the output. This procedure + does not affect the values returned by `current-input-port' and + `current-output-port'. + + `pprint-filter-file' can be used to pre-compile macro-expansion and +thus can reduce loading time. The following will write into +`exp-code.scm' the result of expanding all defmacros in `code.scm'. + (require 'pprint-file) + (require 'defmacroexpand) + (defmacro:load "my-macros.scm") + (pprint-filter-file "code.scm" defmacro:expand* "exp-code.scm") + + +File: slib.info, Node: Time and Date, Next: Vector Graphics, Prev: Printing Scheme, Up: Textual Conversion Packages + +Time and Date +============= + +* Menu: + +* Time Zone:: +* Posix Time:: 'posix-time +* Common-Lisp Time:: 'common-lisp-time + +If `(provided? 'current-time)': + +The procedures `current-time', `difftime', and `offset-time' deal with +a "calendar time" datatype which may or may not be disjoint from other +Scheme datatypes. + + - Function: current-time + Returns the time since 00:00:00 GMT, January 1, 1970, measured in + seconds. Note that the reference time is different from the + reference time for `get-universal-time' in *Note Common-Lisp + Time::. + + - Function: difftime CALTIME1 CALTIME0 + Returns the difference (number of seconds) between twe calendar + times: CALTIME1 - CALTIME0. CALTIME0 may also be a number. + + - Function: offset-time CALTIME OFFSET + Returns the calendar time of CALTIME offset by OFFSET number of + seconds `(+ caltime offset)'. + + +File: slib.info, Node: Time Zone, Next: Posix Time, Prev: Time and Date, Up: Time and Date + +Time Zone +--------- + + (require 'time-zone) + + - Data Format: TZ-string + POSIX standards specify several formats for encoding time-zone + rules. + + : + If the first character of is `/', then + specifies the absolute pathname of a tzfile(5) format + time-zone file. Otherwise, is interpreted as a + pathname within TZFILE:VICINITY (/usr/lib/zoneinfo/) naming a + tzfile(5) format time-zone file. + + + The string consists of 3 or more alphabetic characters. + specifies the time difference from GMT. The + is positive if the local time zone is west of the Prime + Meridian and negative if it is east. can be the + number of hours or hours and minutes (and optionally seconds) + separated by `:'. For example, `-4:30'. + + + is the at least 3 alphabetic characters naming the local + daylight-savings-time. + + + specifies the offset from the Prime Meridian when + daylight-savings-time is in effect. + + The non-tzfile formats can optionally be followed by transition + times specifying the day and time when a zone changes from + standard to daylight-savings and back again. + + ,/