This is bigloo.info, produced by makeinfo version 4.12 from bigloo.texi.

3.1a

  This file documents Bigloo, an implementation of an extended version
of the Scheme programming language.

  Copyright (C) 1992-99, 2000-08 Manuel Serrano

     This program is free software; you can redistribute it
     and/or modify it under the terms of the GNU General Public
     License as published by the Free Software Foundation; either
     version 2 of the License, or (at your option) any later version.

     This program is distributed in the hope that it will be useful,
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.

     You should have received a copy of the GNU General Public
     License along with this program; if not, write to the Free
     Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
     MA 02111-1307, USA.

INFO-DIR-SECTION The Algorithmic Language Scheme
START-INFO-DIR-ENTRY
* bigloo: (bigloo).            The Bigloo Scheme compiler
END-INFO-DIR-ENTRY


File: bigloo.info,  Node: Top,  Next: Acknowledgements,  Prev: (dir),  Up: (dir)


                                         ,-^,
                                   _ ___/ /|/
                               ,;'( )__, ) '
                              ;;  //   L__.
                              '   \    /  '
                                   ^   ^

* Menu:

* Acknowledgements::             Brief history and helpers
* Overview::                     A brief summary of Bigloo facilities
* Modules::                      Modules description
* Core Language::                Syntax, expressions and definitions
* Standard Library::             The Bigloo standard library
* Pattern Matching::             Non linear Bigloo pattern matching
* Fast search::                  Fast string search algorithms.
* Structures and Records::       Various Record data types.
* Object System::                Documentation for the Bigloo object layer
* Threads::                      Bigloo threads
* Regular Parsing::              Pre-compiled regular grammars
* Lalr Parsing::                 Pre-compiled Lalr grammars
* Posix Regular Expressions::    Posix Regular Expressions
* Database::                     Database
* Errors and Assertions::        Bigloo error handling and Bigloo assertions
* Tracing::                      Bigloo tracing facility (user debug)
* Eval::                         Use of the interpreter
* Macro Expansion::              The two available macro schemes
* Parameters::                   Controlling the global programs behaviors
* Command Line Parsing::         Parsing binaries command line invocation
* Explicit Typing::              Improving the compiler's code quality
* C Interface::                  Interfacing to C
* Java Interface::               Interfacing to Java
* SRFIs::                        SRFIs supported by Bigloo
* Bigloo Libraries::             Creating and using your own libraries
* Extending the Runtime System:: Creating and using your own libraries
* DSSSL Support::
* Compiler Description::         Interfacing with the compiler
* User Extensions::              User compiler extensions
* Bee::                          The Bigloo development environment
* Global Index::                 Global Bigloo document index
* Library Index::                Index for forms, functions and variables
* Bibliography::


File: bigloo.info,  Node: Acknowledgements,  Next: Overview,  Prev: Top,  Up: Top

Acknowledgements
****************

Bigloo has been developed at Inria-Rocquencourt by the Icsla team from
1991 to 1994, at the University of Montreal in 1995 and at Digital's
Western Research laboratory in 1996, University of Geneva during 1997
and from the end of 1997 at the University of Nice.

  I would like to express my gratitude to _Hans J. Boehm_ for his
Garbage Collector [BoehmWeiser88, Boehm91], _Jean-Marie Geffroy_ for his
pattern-matching compiler [QueinnecGeffroy92], _Dominique Boucher_ for
his Lalr grammar compiler, _William Clinger_ for his syntax expansion
implementation and _Dorai Sitaram_ for his contribution with the
`pregexp' package and its documentation. I also especially thank
_Christian Queinnec_ for all his useful remarks, help, suggestions and
teaching.

  Other people have helped me by providing useful remarks, bug fixes or
code improvements. I thank all of them and especially _Luc Moreau_,
_John Gerard Malecki_, _David Halls_ and _David Gurr_.

  I thank _Barrie Stott_ for his help in making much of the
documentation more idiomatic. Of course, any remaining errors are still
mine.

  This release of Bigloo may still contain bugs. If you notice any,
please forgive me and send a mail message to the following address:
<bigloo@sophia.inria.fr>.

  This is Bigloo documentation version 3.1a, May 2008.


File: bigloo.info,  Node: Overview,  Next: Modules,  Prev: Acknowledgements,  Up: Top

1 Overview of Bigloo
********************

Bigloo is an implementation of an extended version of the Scheme
programming language. Without its extensions Bigloo does not entirely
conform to Scheme as defined in the Revised(5) Report on on the
Algorithmic Language Scheme (henceforth R5RS) (see *note Top:
(r5rs.info)Top.).  The two reasons are:

   * Bigloo produces C files. C code uses the C stack, so some programs
     can't be properly tail recursive. Nevertheless all simple tail
     recursions are compiled without stack consumption.

   * Alternatively, Bigloo may produce JVM (Java Virtual Machine byte
     code) class files. These classes may use regular Java classes.

   * Bigloo can also produce .NET class files. These classes may use
     regular .NET machines such as mono.

   * Bigloo is a module compiler. It compiles modules into `.o',
     `.class', or `.obj' files that must be linked together to produce
     stand alone executable programs, JVM jar files, or .NET programs.

  However, we designed Bigloo to be as close as possible to the R5RS.
Hence, when Bigloo includes a feature that is extracted from Scheme and
implemented as normal, this feature is only mentioned in this document
and not fully described.

1.1 SRFI
========

The Bigloo version 3.1a supports the following SRFIs:

   * `srfi-0' (conditional execution).

   * `srfi-2' (AND-LET*: an AND with local bindings, a guarded LET*
     special form).

   * `srfi-6' (Basic String Ports).

   * `srfi-8' (Binding to multiple values).

   * `srfi-9' (_Records_ specification).

   * `srfi-18' (Multithreading support).

   * `srfi-22' (script interpreter invocation).

   * `srfi-28' (Basic Format Strings).

   * `srfi-30' (Multi-line comments).

1.2 Separate compilation
========================

To allow and stimulate separate compilation, Bigloo compiles modules
instead of entire programs. A module is composed of a module
declaration and a module body, where a module body can be thought of as
an incomplete Scheme program.

  Bigloo strictly enforces variable bindings. That is, it is illegal in
a body to refer to unbound variables.

  In a module declaration, some variables can be declared to be
immutable functions. For such variables, the compiler can then check if
the number of arguments for some function calls are correct or not.
When an arity mismatch is detected, Bigloo signals an error and aborts
the compilation process.

1.3 C interface
===============

The goal of the design of Bigloo is to allow the merging of high and low
level programming. This means that Bigloo is designed to be fully
connected to the already existing outside world of C.

  This connection has two components: a function call interface and a
data storage interface. Bigloo code is able to call C code and vice
versa; Bigloo data storage is accessible from C and vice versa. There
are no frontiers between the Bigloo and C worlds.

1.4 Java interface
==================

Since release 2.3, Bigloo is able to produce Java Virtual Machine byte
codes in addition to C code. By producing class files, it is possible
to connect Scheme code and Java code in the same spirit as the Scheme
and C connection.

  This connection has two components: a function call interface and a
data storage interface. Bigloo code is able to call Java code and vice
versa; Bigloo data storage is accessible from Java and vice versa.
There are no frontiers between the Bigloo and Java worlds.

1.5 Object language
===================

Since release 1.9, Bigloo has included an object system. This system
belongs to the CLOS [Bobrow et al. 88] object system family but whose
design has been mainly inspired by C. Queinnec's MEROON [Queinnec93]. It
is based on _ad-hoc_ polymorphism (generic functions and methods), uses
single inheritance and mono-dispatch, and provides the user with
introspection facilities.

1.6 Threads
===========

Since release 2.4d, Bigloo has included a thread library. Bigloo
supports Fair threads that are cooperative threads run by a fair
scheduler which gives them equal access to the processor. Fair threads
can communicate using broadcast events and their semantics does not
depends on the executing platform. Fine control over fair threads
execution is possible allowing the programming of specific user-defined
scheduling strategies.

1.7 SQL
=======

Since release 2.7b, Bigloo includes a SQL binding. Namely, the C Bigloo
runtime system can access the facilities offered by SQLite
(`http://www.sqlite.org/').

1.8 Type annotations
====================

Type information, related to variable or function definitions, can be
added to the source code. If no type information is provided, runtime
checks will be introduced by the compiler to ensure normal execution,
provided that the user has not used compilation flags to prevents this.
If type information is added, the compiler statically type checks the
program and refuses ones that prove to be incorrect.

1.9 Unicode support
===================

Bigloo supports UCS-2 Character encoding and also provides conversion
functions between UTF-8 and UCS-2. It still maintains traditional
ISO-LATIN1 characters and strings.

1.10 DSSSL
==========

Bigloo helps the DSSSL programmer by supporting keywords, named
constants and keyword functions.


File: bigloo.info,  Node: Modules,  Next: Core Language,  Prev: Overview,  Up: Top

2 Modules
*********

A modules is a compiler and interpreter entity. Modules have been first
designed for the compiler that compiles modules and then, links them
against libraries in order to produce executables. A module may be
split into several files but a file cannot contain more than _one_
module. A module is made of a module clause that is a list for which
the `car' is the symbol `module' and followed by any Bigloo expression
(that is definitions or expressions). The module clause names the
module and defines the scope of the definitions. At last, the module
clause is also the place where foreign bindings are defined and where
classes are defined. Recent versions of Bigloo (since 2.7b) fully
supports modules from the interpreter.

* Menu:

* Program Structure::
* Module Declaration::
* Module Initialization::
* Qualified Notation::
* Inline Procedures::
* Module Access File::
* Reading Path::


File: bigloo.info,  Node: Program Structure,  Next: Module Declaration,  Prev: Modules,  Up: Modules

2.1 Program Structure
=====================

A Bigloo program is composed of one or more Bigloo modules where a
module is defined by the following grammar:

     <module>             ==> <module-declaration> <module-body>
     <module-declaration> ==> the module declaration
     <module-body>        ==> the module body

  A module is not related to a specific file and can be spread over
several files if that is convenient. In particular, there is no
relationship between module names and file names. The module declaration
(see *note Module Declaration::) must be the first expression in the
first of the files containing the module; other expressions form the
body of the module. The module body (see *note Core Language::)
contains global variables, function definitions and _top level_
expressions (see *note Expressions::).


File: bigloo.info,  Node: Module Declaration,  Next: Module Initialization,  Prev: Program Structure,  Up: Modules

2.2 Module declaration
======================

The module declaration form is

 -- bigloo syntax: module name clause ...
     This form defines a module and must be the first in the file.  The
     argument NAME is a symbol naming the module. If the same module
     name is used more than once, Bigloo signals an error. The runtime
     library is composed of modules that are read when a user module is
     compiled and hence, if a user module has the same name as one of
     the library modules, an error is signaled.

     A simple module can be:

          (module foo)

          (display "this is a module")

     The first line here is the complete module definition, the last
     line is the complete module body and together they form a complete
     Bigloo program. If these lines were stored in file `zz.scm',
     invoking `bigloo zz.scm' would create the executable `a.out'
     which, when obeyed, would display `this is a module' on the
     terminal.

     _Note:_ Some special identifiers are reserved and can't be used to
     name modules.  If such an identifier is used, the compiler will
     produce the message:

          #(module t
          #^
          # *** ERROR:bigloo:TOP-LEVEL:Parse error
          # Illegal module name -- (MODULE eval ...

     The list of reserved identifiers may be enlarged for next release.
     For the current release that list is made of: `eval', `foreign' and
     `t'.

  Module CLAUSEs can be:

 -- bigloo module clause: main name
     This clause defines the entry point for a stand alone application
     to be procedure NAME of arity one. Bigloo invokes this procedure
     at the beginning of execution providing the list, composed of the
     shell command line arguments, as its single argument.

          (module foo
             (main start))

          (define (start argv)
             (display argv)
             (newline))

     Then if this program is compiled into `foo' and invoked using the
     command `foo -t bar', the list which is the argument for the main
     procedure `start' would be `("foo" "-t" "bar")'.

     The special form `args-parse' helps main function argument parsing
     (*note Command Line Parsing::).

 -- bigloo module clause: include file-name ...
     This is a list of FILE-NAMEs to be included in the source file.
     Include files are not modules and may have a special syntax. Thus,
     besides containing Bigloo expressions, they can contain import and
     include clauses, which must be written in a single list whose
     first element is the keyword `directives'. Includes files can be
     used to include implementation-neutral Scheme expressions and
     definitions in a Bigloo module. Here is an example of an include
     file.

          ;; `foo.sch'
          (define-struct point x y)

     and the module that includes the `foo.sch' file:

          ;; `foo.scm'
          (module foo
             (include "foo.sch"))

          (print (point 1 2))

     Include files, may contain module information. This is the role of
     the include `directives' clause here illustrated with the `bar.sch'
     example:

          ;; `bar.sch'
          ;; the directives
          (directives (include "foobar.sch")
                      (import  hux))

          ;; expressions
          (define (gee x) (print x))

 -- bigloo module clause: import import ...
     An IMPORT is a list of the form:

          <import>      ==> <iclause> ...
          <iclause>     ==> (<bind-name> ... <bind-name> <module-name> <file-name> ...)
                          | (<bind-name> ... <bind-name> <module-name>)
                          | <module-name>
                          | (<module-name> <file-name> ...)
          <bind-name>   ==> <r5rs-ident>
          <module-name> ==> <r5rs-ident>
          <file-name>   ==> <string>

     The first alternative in ICLAUSE imports the variable named
     BIND-NAME which is defined in the module MODULE-NAME, located in
     the files FILE-NAME .... The second does the same but without
     specifying the name of the file where the module is located.  The
     third and the fourth form import all the exported variables of the
     module MODULE-NAME.

     Note: The need for specifying in which files modules are located
     comes from the fact that there is no automatic mapping between
     module names and files names. Such a mapping can be defined in a
     "module access file" (*note Module Access File::) or in the import
     clause itself, as in the first and fourth alternatives in ICLAUSE
     above.

     Here is an example of an import clause:

          (module foo
             (import
                ;; import all `bar' exported bindings:
                bar
                ;; import the `hux' binding exported by
                ;; the module `hux':
                (hux hux)
                ;; import the `fun1', `fun2' and `fun3' bindings exported by
                ;; the module `mod':
                (fun1 fun2 fun3 mod)
                ;; import all `gee' bindings. the `gee' module
                ;; is located in a file called `gee.scm':
                (gee "gee.scm")))


 -- bigloo module clause: use use ...
     `use' has the same meaning as `import' except that modules which
     are _used_ are not initialized (*note Module Initialization::).
     Used modules are read before imported modules.

 -- bigloo module clause: with with ...
     This clause specifies a list of modules which have to be
     initialized at runtime and is used to force the initialization of
     modules which are never imported but which are required by an
     application (*note Embedded Bigloo applications::).

 -- bigloo module clause: export export ...
     In order to make a module's global bindings available to other
     modules, they have to be _exported_. Export clauses are in charge
     of this task and an EXPORT is a list of the form:

          <export>  ==> <eclause> ...
          <eclause> ==> <ident>
                      | (inline <ident> <ident> ...)
                      | (generic <ident> <ident> <ident> ...)
                      | (macro <ident> <ident> ...)
                      | (syntax <ident> <ident> ...)
                      | (<ident> <ident> ...)
                      | <class>

     The first form of ECLAUSE allows the variable IDENT be exported,
     the second allows the function IDENT, always regarded as immutable
     when exported this way, to be exported and the third exports an
     inline-procedure (*note Inline Procedures::) whose name is
     extracted from the first IDENT after the word INLINE. The last two
     are both connected with Bigloo's object system.  The GENERIC
     clause exports generic functions (*note Generic functions::) and
     CLASS clause exports classes (*note Class declaration::).

     Note: Only bindings defined in module `m' can be _exported_ by `m'
     (i.e. bindings _imported_ by `m' cannot be _exported_ by `m').

     Type information, specified in any IDENT in an export clause, is
     used by Bigloo. Where no type information is given, a default
     generic type named `obj' is used.

     Note: The last formal argument of a multiple arity function can
     not be typed because this argument is bound to be a `pair' or
     `null'. This union cannot be denoted by any type.

     Here is an example of the module `foo' that exports bindings:

          (module foo
             (export
                ;; export the `bar' mutable variable
                bar
                ;; export the `hux' function. this
                ;; function takes exactly two arguments
                (hux x y)
                ;; export the inline function `gee'
                ;; that takes at least one argument.
                (inline gee x . z)))


 -- bigloo module clause: static static ...
     A `static' clause has exactly the same syntax as an export clause.
     However, bindings declared static are local to the module. Since
     the default scope of all bindings is static, `static' module
     clauses are useful only for program documentation.


 -- bigloo module clause: from from ...
     `from' clauses have the syntax of `import' clauses. The allow the
     re-exportation of imported bindings. That is, any module can
     export any bindings imported via a FROM clause.

     As an example, suppose we have module `bar':

          (module bar
             (export (fun)))

          (define (fun) "bar")

     Now, suppose we have a module `foo' that imports `bar', by the
     means of a `from' clause. Module `foo' is able to re-export the
     `bar' binding of module `bar':

          (module foo
             (from (fun bar "bar.scm")))

     A third module, let's name it `gee', importing module `foo', can
     see the binding for function `bar':

          (module gee
             (import (foo "foo.scm")))

          (print (fun))

     This feature is very useful when compiling modules exporting
     functions with type annotations. In particular, one may write:

          (module foo
            (export (class c1 x)))

     Then,
          (module bar
            (import foo)
            (from foo)
            (export (fun::c1)))

          (define (fun)
             (instantiate::c1 (x 10)))

     And,

          (module gee
             (import bar)
             (main main))

          (define (main x)
             (let ((o (fun)))
                (print o)
                (print (c1? o))))


 -- bigloo module clause: load load ...
     A LOAD is a list of the form:

          <load>    ==> <lclause> ...
          <lclause> ==> (<module-name> <file-name>)
                      | <module-name>

     This clause forces Bigloo to load the module specified in the
     LCLAUSE in the environment used by the macro expansion mechanism.
     This means that the user's macros can use all the bindings of all
     the `load'ed modules but the `load'ed bindings remains unknown to
     the compiler.

     If the module `foo' is defined by:

          (module foo
             (export (foo x)))

          (define (foo x)
             `(cons ,x ,x))

     then,

          (module gee
             (load (foo "foo.scm")))

          (define-macro (gee x)
             `(cons ,(-fx x 1) ,(foo x)))

          (gee 5)   ==> (cons 4 (cons 5 5))
                    => (4 5 . 5)

 -- bigloo module clause: eval eval...
     This form allows interactions between compiled code and interpreted
     code. (See the Section *note Eval command line options: Eval. for a
     presentation of compilation flags that enable compilation tuning
     for `eval'.)  Each EVAL has the following syntax:

          <eval> ==> (export-all)
                   | (export-module)
                   | (export-exports)
                   | (export <bind-name>)
                   | (export (@ <bind-name> <module-name>))
                   | (import <bind-name>)
                   | (class <bind-name>)
     
     The first clause, `(export-all)', exports all the variables bound
     in the module (i.e., the variables defined in the module and the
     imported variables).  The second clause, `(export-module)', exports
     all the module's variables (those declared static and exported) to
     the interpreter; the third exports all the exports (i.e. the ones
     present inside an `export' clause) variables to the interpreter;
     the fourth and fifth clause each export one variable to the
     interpreter. The last clause imports a variable from the
     interpreter and all such imported variables are immutable (i.e.
     they cannot be the first argument of a `set!'  expression with the
     compiled code). Variables that are exported to the evaluators
     _must_ be exported.  If a variable is exported to the evaluators
     but not exported within an `export' clause, the compiler will
     produce an error message.

          (module foo
             (export (fib x))
             (eval (export fib)
                   (import bar)))

          (define (fib x) ...)
          (print bar)

     The clause `(class <bind-name>)' exports a class definition to the
     interpreter. This makes the class constructor, the class predicate
     and the slots access functions available from the interpreter. The
     form    `(instantiate::CLASS ...)' and    `(with-access::CLASS
     ...)'  are also available from the interpreter.

 -- bigloo module clause: extern extern ...
     Extern (aka foreign) clauses will be explained in the foreign
     interface (*note C Interface::).

 -- bigloo module clause: java java ...
     Java clauses will be explained in the Java interface (*note Java
     Interface::).

 -- bigloo module clause: option option ...
     This clause enables variables which affect compilation to be set
     from inside a module and since the expressions, OPTION ..., are
     evaluated _when compiling_, no code is compiled for them.  They
     are allowed to make side effects and to change the values of the
     global variables which describe how the compiler must compile.
     Usually they allow the control variables, which are described when
     Bigloo is invoked with the `-help2' option, to be set as in the
     following example:

          (module examplar
             (option (set! *debug* 3)
                     (set! *verbose* 2)))

          (print 'dummy)

     Whatever arguments are passed on the command line, Bigloo will
     compile this module in both verbose mode and debug mode.

 -- bigloo module clause: library library ...
     This clause enables libraries (*note Bigloo Libraries::) when
     compiling and linking Bigloo modules. The expressions LIBRARY ...
     are symbols naming the libraries to be used.

     Here is an example of a module declaration which makes use of a
     library named `format':

          (module test
             (library format)
             (main    test-format)
             (import  (test2 "test2.scm")))


 -- bigloo module clause: type type ...
     This forms is used to define builtin Bigloo types. It is not
     recommended to use it in user programs. So, it is left
     undocumented.


File: bigloo.info,  Node: Module Initialization,  Next: Qualified Notation,  Prev: Module Declaration,  Up: Modules

2.3 Module initialization
=========================

_Initializing_ a module means evaluating, at runtime, its top level
forms (global bindings are top level forms).

  When a module, MODULE1, imports a module, MODULE2, MODULE2 is
initialized before MODULE1. Modules are initialized only once, nothing
being done if a module already met during initialization is met again.
Library modules are initialized before user modules and imported
modules are initialized in the same order as they appear in import
clauses.

  Here is a first example with two modules. First the module `foo':

     ;; module foo
     (module foo
        (main main)
        (import (bar "bar.scm")))

     (define (main argv)
        (print "argv: " argv))
     (print "foo")

  Then the module `bar'
     ;; module bar
     (module bar)

     (print "bar")

  These can be compiled into the executable A.OUT with:
     $ bigloo -c foo.scm
     $ bigloo -c bar.scm
     $ bigloo foo.o bar.o

  Execution of A.OUT produces:
     $ a.out
        -| bar
           foo
           argv: (a.out)

  The explanation is:
   * module `foo' contains the program entry point so this is where
     initialization begins.

   * because `foo' imports module `bar', `bar' must be  initialized
     _before_ `foo'. This explains why the word `bar'  is printed
     before anything else.

   * module initialization for `foo' is completed before `main'  is
     called. This explains why word `foo' is printed before `main'  is
     entered.

  Let's consider another example with 3 modules:
     ;; `module1'
     (module module1
        (main main)
        (import (module2 "module2.scm")))

     (define (main argv)
        (print "argv: " argv))

     (print "module1")

  The second module:
     ;; `module2'
     (module module2
        (import (module3 "module3.scm")))

     (print "module2")

  The third module:
     ;; `module3'
     (module module3
        (import (module1 "module1.scm")))

     (print "module3")

  Compile with:
     $ bigloo module1.scm -c
     $ bigloo module2.scm -c
     $ bigloo module3.scm -c
     $ bigloo module1.o module2.o module3.o

  Execution produces:

     $ a.out
        -| module3
           module2
           module1
           argv: (a.out)

  The order of module initialization can be explicitly specified using
`with' and `use' clauses.


File: bigloo.info,  Node: Qualified Notation,  Next: Inline Procedures,  Prev: Module Initialization,  Up: Modules

2.4 Qualified notation
======================

Global variables can be referenced using implicit notation or using
_qualified_ notation. Implicit notation is used when variables are
referenced just by their name whereas qualified notation is used when
variables are referenced by their name and the name of the module which
defines them. Qualified notation has the following syntax:

     (@ <bind-name> <module-name>)

and is useful when several imported modules export a variable with the
same name. Using qualified notations instead of short notation only
affects compilation.

  When several variables are defined under the same identifier, the
compiler uses the two following rules in order to decide which variable
is selected by an implicit reference: 1) the variable defined in a
module has a higher precedence than all imported variables, 2) imported
variables have a higher precedence than library variables.


File: bigloo.info,  Node: Inline Procedures,  Next: Module Access File,  Prev: Qualified Notation,  Up: Modules

2.5 Inline procedures
=====================

Bigloo allows procedures called _inline_ and which differ from normal
ones only in the type of code planted.  An inline procedure is a first
class object which can be manipulated in the same way as any other
procedure but when Bigloo sees a reference to one, rather than
generating a C function call to the function, the body of the inline
procedure is open-coded.  The definition of an inline is given in the
following way:

 -- bigloo syntax: define-inline (name args ...) body
 -- bigloo syntax: define-inline (name args ... . arg) body
     Apart from the initial word, this form has the same syntax as that
     used by `define' for procedures. Inline procedures are exportable
     which means that the compiler scans imported files to find the
     bodies of all inline procedures. Here is a small example of a
     module which exports an inline and a module which imports it.

          ;; the exporter module
          (module exporter
                  (export (inline make-list . objs)))

          (define-inline (make-list . objs) objs)

          ;; the importer module
          (module importer
                  (import exporter))

          (print (make-list 1 2 3 4 5))

     Because of the open-coding of the exporter procedure, the above
     print statement is equivalent to:

          (print (let ((objs (list 1 2 3 4 5)))
                    objs))

     Any procedure can be an inline. Also any exported procedure can be
     an inline provided all global variables and functions it uses are
     also exported.

     Note: Bigloo can decide to inline procedures declared with `define'
     but this can be achieved only with local procedures whereas
     procedures declared with the `define-inline' form are open-coded
     even through module importation.

     Note: Procedures declared _inline_ are macro expanded with the
     macro defined in the module where they are invoked. That is, if
     module `module1' declares an inline procedure `p' and module
     `module2' imports it, `p' may have two different macro-expansions:
     one for `module1' and one for `module2'.


File: bigloo.info,  Node: Module Access File,  Next: Reading Path,  Prev: Inline Procedures,  Up: Modules

2.6 Module access file
======================

Bigloo is different from languages such as C where a module is defined
by a file. For Bigloo, the module name is not necessarily the name of
the file where the text of the module is written and modules can even
be split across several files.

  Since modules are defined independently of files, it is necessary to
make a link between a module and its files and there are two ways of
doing this.  Choosing an import clause where the file-names are
specified or creating a "module access file". Such a file must contain
only one LIST, each element of the list being of the form:

  (module-name "file-name" ... "file-name")

Use the `-afile <file>' option to specify the "module access file" when
compiling. By default Bigloo checks if a file named `.afile' exists. If
it exists it is loaded as a module access file.

  *Note The Bigloo command line: Compiler Description.

  Note: The Bigloo distribution contains a tool, `bglafile', that can
automatically build a "module access file". See the manpage for
`bglafile' for details.


File: bigloo.info,  Node: Reading Path,  Prev: Module Access File,  Up: Modules

2.7 Reading path
================

Imported, included or loaded files are sought first in the current
directory and then in the directories, sequentially from start to end,
of the list in the `*load-path*' variable. This variable, initially set
to the empty list, can be reset by the `-I' option of the compiler.


File: bigloo.info,  Node: Core Language,  Next: Standard Library,  Prev: Modules,  Up: Top

3 Core Language
***************

This chapter presents the Bigloo basics. It presents the elements that
compose the body of a module (see *note Modules::).

* Menu:

* Syntax::                      Identifiers and typed identifiers
* Comments::                    Bigloo comments
* Expressions::                 Expressions
* Definitions::                 Global definitions


File: bigloo.info,  Node: Syntax,  Next: Comments,  Prev: Core Language,  Up: Core Language

3.1 Syntax
==========

The syntax of Bigloo is that of Scheme (a parenthesis based one) with
two exceptions: type information and multi-line comments. Type
information is supplied when identifiers are introduced (via `lambda',
`let', `define', ...) and those identifiers holding type information are
referred to as typed identifiers.

  They are defined by the following grammar:

     <ident>        ==> <r5rs-ident> | <typed-ident>
     <typed-ident>  ==> <r5rs-ident>::<r5rs-ident>
     <r5rs-ident>   ==> the standard Scheme identifiers

  For details of the standard Scheme identifiers, see *note token:
(r5rs.info)Lexical structure.

  Multi-lines comments (see `http://srfi.schemers.org/srfi-30/') are
defined as:

     <ident>        ==> <r5rs-ident> | <typed-ident>
     <comment>      ==> ;<all subsequent characters up to a line break>
            	       | #| <comment-text> (<comment> <comment-text>)* |#
     <comment-text> ==> <character sequence not containing #| or |#>


File: bigloo.info,  Node: Comments,  Next: Expressions,  Prev: Syntax,  Up: Core Language

3.1.1 Comments
--------------

Comments and whitespaces are the same as in *note r5rs.info:
(R5RS)Whitespace and comments.

     ;;; The FACT procedure computes the factorial
     ;;; of a non-negative integer.
     (define fact
       (lambda (n)
         (if (= n 0)
             1        ;; Base case: return 1
             (* n (fact (- n 1))))))

  In addition, Bigloo supports _s-expressions_ comments. These are
introduced with the `#;' syntax:

     ;;; The FACT procedure computes the factorial
     ;;; of a non-negative integer.
     (define fact
       (lambda (n)
         #;(if (< n 2) 1 (* #;n (fact (- n 1))))
         (if (= n 0)
             1
             (* n (fact (- n 1))))))


File: bigloo.info,  Node: Expressions,  Next: Definitions,  Prev: Comments,  Up: Core Language

3.1.2 Expressions
-----------------

Bigloo expressions are the same as in *note r5rs.info:
(R5RS)Expressions.  Bigloo has more syntactic keywords than Scheme. The
Bigloo syntactic keywords are:

     =>                      do                    or
     and                     else                  quasiquote
     begin                   if                    quote
     case                    lambda                set!
     cond                    let                   unquote
     unquote-splicing        define                let*
     delay                   letrec                module
     labels                  try                   define-struct
     unwind-protect          bind-exit             define-inline
     regular-grammar         lalr-grammar          regular-search
     define-expander         define-macro          match-case
     match-lambda            pragma                failure
     assert                  define-generic        define-method
     instantiate             duplicate             with-access
     widen!                  shrink!               multiple-value-bind
     let-syntax              letrec-syntax         define-syntax
     cond-expand             receive               args-parse
     define-record-type      and-let*

All other non atomic Bigloo forms are evaluated as function calls or
macro class.

 -- syntax: <variable>
 -- syntax: quote datum
 -- syntax: `''datum
 -- syntax: <constant>
          (define x 28)                          =>
          x                                      => 28
          (quote a)                              => A
          (quote #(a b c))                       => #(A B C)
          (quote (+ 1 2))                        => (+ 1 2)
          'a                                     => A
          '#(a b c)                              => #(A B C)
          '()                                    => ()
          '(+ 1 2)                               => (+ 1 2)
          '(quote a)                             => (QUOTE A)
          '"abc"                                 => "abc"
          "abc"                                  => "abc"
          '145932                                => 145932
          145932                                 => 145932
          '#t                                    => #t
          #t                                     => #t

 -- syntax: operator operand ...
          (+ 3 4)                                => 7
          ((if #f + *) 3 4)                      => 12
          ((lambda (x) (+ 1 x)) 5)               => 6

 -- syntax: lambda formals body
          (lambda (x) (+ x x))                   => _a procedure_
          ((lambda (x) (+ x x)) 4)               => 8

          (define reverse-subtract
            (lambda (x y) (- y x)))
          (reverse-subtract 7 10)                => 3

          (define add4
            (let ((x 4))
              (lambda (y) (+ x y))))
          (add4 6)                               => 10

          ((lambda x x) 3 4 5 6)                 => (3 4 5 6)
          ((lambda (x y . z) z)
           3 4 5 6)                              => (5 6)

 -- syntax: if test consequent [alternate]
          (if (> 3 2) 'yes 'no)                  => yes
          (if (> 2 3) 'yes 'no)                  => no
          (if (> 3 2)
              (- 3 2)
              (+ 3 2))                           => 1

 -- syntax: set! variable expression
          (define x 2)
          (+ x 1)                                => 3
          (set! x 4)                             => _unspecified_
          (+ x 1)                                => 5

 -- library syntax: cond clause clause ...
     Bigloo considers `else' as a keyword. It thus ignores clauses
     following an `else'-clause.

          (cond ((> 3 2) 'greater)
                ((< 3 2) 'less))                 => greater

          (cond ((> 3 3) 'greater)
                ((< 3 3) 'less)
                (else 'equal))                   => equal

          (cond ((assv 'b '((a 1) (b 2))) => cadr)
                (else #f))                       => 2

 -- library syntax: case key clause clause ...
          (case (* 2 3)
            ((2 3 5 7) 'prime)
            ((1 4 6 8 9) 'composite))            => composite
          (case (car '(c d))
            ((a) 'a)
            ((b) 'b))                            => _unspecified_
          (case (car '(c d))
            ((a e i o u) 'vowel)
            ((w y) 'semivowel)
            (else 'consonant))                   => consonant

 -- library syntax: and test ...
          (and (= 2 2) (> 2 1))                  => #t
          (and (= 2 2) (< 2 1))                  => #f
          (and 1 2 'c '(f g))                    => (f g)
          (and)                                  => #t

 -- bigloo syntax: and-let* test ...
          (and-let* ((x 1) (y 2)) (cons x y))    => (1 . 2)
          (and-let* ((x 1) (z #f)) x)            => #f

          (and-let* ((my-list (compute-list)) ((not (null? my-list))))
                    (do-something my-list))

          (define (look-up key alist)
            (and-let* ((x (assq key alist))) (cdr x)))

          (or (and-let* ((c (read-char))
                         ((not (eof-object? c))))
                        (string-set! some-str i c)
                        (set! i (+ 1 i)))


 -- library syntax: or test ...
          (or (= 2 2) (> 2 1))                   => #t
          (or (= 2 2) (< 2 1))                   => #t
          (or #f #f #f)                          => #f
          (or (memq 'b '(a b c))
              (/ 3 0))                           => (b c)

 -- library syntax: let [name] (binding ...) body
          (let ((x 2) (y 3))
            (* x y))                             => 6

          (let ((x 2) (y 3))
            (let ((x 7)
                  (z (+ x y)))
              (* z x)))                          => 35

          (let loop ((l '(1 2 3)))
             (if (null? l)
                 '()
                 (cons (+ 1 (car l))
                       (loop (cdr l)))))         => (2 3 4)

     Bigloo's named let differs from R5Rs named let because NAME is
     bound in BINDING. That is,

          (let ((l 'a-symbol))
            (let l ((x l))
               x))                               => #<procedure>

     while R5Rs states that,

          (let ((l 'a-symbol))
            (let l ((x l))
               l))                               => a-symbol

 -- library syntax: let* (binding ...) body
          (let ((x 2) (y 3))
            (let* ((x 7)
                   (z (+ x y)))
              (* z x)))                          => 70

 -- library syntax: letrec (binding ...) body
          (letrec ((even?
                    (lambda (n)
                      (if (zero? n)
                          #t
                          (odd? (- n 1)))))
                   (odd?
                    (lambda (n)
                      (if (zero? n)
                          #f
                          (even? (- n 1))))))
            (even? 88))
                                                 => #t

 -- bigloo syntax: labels ((name (arg ...) body) ...) body
     The syntax is similar to the Common Lisp one [Steele90], where
     created bindings are immutable.

          (labels ((loop (f l acc)
                         (if (null? l)
                             (reverse! acc)
                             (loop f (cdr l) (cons (f (car l)) acc)))))
             (loop (lambda (x) (+ 1 x)) (list 1 2 3) '()))
             => (2 3 4)

 -- library syntax: begin expression expression ...
          (define x 0)

          (begin (set! x 5)
                 (+ x 1))                        => 6

          (begin (display "4 plus 1 equals ")
                 (display (+ 4 1)))              => _unspecified_
                                                 -| 4 plus 1 equals 5

 -- library syntax: do ((variable init step) ...) (test expression ...)
          body
          (do ((vec (make-vector 5))
               (i 0 (+ i 1)))
              ((= i 5) vec)
            (vector-set! vec i i))               => #(0 1 2 3 4)

          (let ((x '(1 3 5 7 9)))
            (do ((x x (cdr x))
                 (sum 0 (+ sum (car x))))
                ((null? x) sum)))                => 25

 -- library syntax: delay expression

 -- syntax: quasiquote template
 -- syntax: ` template
          `(list ,(+ 1 2) 4)                     => (list 3 4)
          (let ((name 'a)) `(list ,name ',name))
                    => (list a (quote a))
          `(a ,(+ 1 2) ,@(map abs '(4 -5 6)) b)
                    => (a 3 4 5 6 b)
          `((`foo' ,(- 10 3)) ,@(cdr '(c)) . ,(car '(cons)))
                    => ((foo 7) . cons)
          `#(10 5 ,(sqrt 4) ,@(map sqrt '(16 9)) 8)
                    => #(10 5 2 4 3 8)
          `(a `(b ,(+ 1 2) ,(foo ,(+ 1 3) d) e) f)
                    => (a `(b ,(+ 1 2) ,(foo 4 d) e) f)
          (let ((name1 'x)
                (name2 'y))
            `(a `(b ,,name1 ,',name2 d) e))
                    => (a `(b ,x ,'y d) e)
          (quasiquote (list (unquote (+ 1 2)) 4))
                    => (list 3 4)
          '(quasiquote (list (unquote (+ 1 2)) 4))
                    => `(list ,(+ 1 2) 4)
               __i.e., (quasiquote (list (unquote (+ 1 2)) 4))


File: bigloo.info,  Node: Definitions,  Prev: Expressions,  Up: Core Language

3.1.3 Definitions
-----------------

Global bindings are introduced by the `define' form:

 -- syntax: define variable expression
 -- syntax: define (variable arg ...) body
          (define add3
            (lambda (x) (+ x 3)))
          (add3 3)                               => 6
          (define first car)
          (first '(1 2))                         => 1

  *Note r5rs.info: Definitions, for more details. The Bigloo module
language (See *note Module Declaration::) enables _exports_ and
_imports_ of global definitions.


File: bigloo.info,  Node: Standard Library,  Next: Pattern Matching,  Prev: Core Language,  Up: Top

4 Standard Library
******************

This chapter presents the Bigloo standard library. Bigloo is mostly
R5RS compliant but it proposes many extensions to this standard.  In a
first section (*note Scheme Library::) the Bigloo R5RS support is
presented. This section also contains various function that are not
standard (for instance, various functions used to manage a file
system). Then, in the following sections (*note Serialization::, *note
Bit Manipulation::, and *note System Programming:: Bigloo specific
extensions are presented. Bigloo input and output facilities constitue
a large superset of the standard Scheme definition. For this reason
they are presented in a separate section (*note Input and Output::).

* Menu:

* Scheme Library::
* Input and Output::
* Serialization::
* Bit Manipulation::
* Weak Pointers::
* Hash Tables::
* System Programming::
* Date::
* Digest::


File: bigloo.info,  Node: Scheme Library,  Next: Input and Output,  Up: Standard Library

4.1 Scheme Library
==================

When the definition of a procedure or a special form is the same in
Bigloo and Scheme, we just mention its name; otherwise, we explain it
and qualify it as a "bigloo procedure".

* Menu:

* Booleans::
* Equivalence Predicates::
* Pairs And Lists::
* Symbols::
* Keywords::
* Numbers::
* Characters::
* UCS-2 Characters::
* Strings::
* Unicode (UCS-2) Strings::
* Vectors::
* Homogeneous Vectors (SRFI-4)::
* Control Features::


File: bigloo.info,  Node: Booleans,  Next: Equivalence Predicates,  Up: Scheme Library

4.1.1 Booleans
--------------

The standard boolean objects are `#t' and `#f'.  Note: the empty list
is true.

 -- library procedure: not obj
     `not' returns #t if OBJ is false, and returns `#f' otherwise.

          (not #t)                               => #f
          (not 3)                                => #f
          (not (list 3))                         => #f
          (not #f)                               => #t
          (not '())                              => #f
          (not (list))                           => #f
          (not 'nil)                             => #f

 -- library procedure: boolean? obj
     `Boolean?' returns #t if OBJ is either #t or #f and returns #f
     otherwise.

          (boolean? #f)                          => #t
          (boolean? 0)                           => #f
          (boolean? '())                         => #f


File: bigloo.info,  Node: Equivalence Predicates,  Next: Pairs And Lists,  Prev: Booleans,  Up: Scheme Library

4.1.2 Equivalence predicates
----------------------------

 -- procedure: eqv? obj1 obj2
 -- procedure: eq? obj1 obj2
     `eqv?' and `eq?' are equivalent in Bigloo.

          (eq? 'a 'a)                            =>  #t
          (eq? '(a) '(a))                        =>  _unspecified_
          (eq? (list 'a) (list 'a))              =>  #f
          (eq? "a" "a")                          =>  _unspecified_
          (eq? "" "")                            =>  _unspecified_
          (eq? '() '())                          =>  #t
          (eq? 2 2)                              =>  _unspecified_
          (eq? #\A #\A)                          =>  _unspecified_
          (eq? car car)                          =>  #t
          (let ((n (+ 2 3)))
            (eq? n n))                           =>  _unspecified_
          (let ((x '(a)))
            (eq? x x))                           =>  #t
          (let ((x '#()))
            (eq? x x))                           =>  #t
          (let ((p (lambda (x) x)))
            (eq? p p))                           =>  #t

     Since Bigloo implements `eqv?' as `eq?', the behavior is not
     always conforming to R5RS.
          (eqv? 'a 'a)                           =>  #t
          (eqv? 'a 'b)                           =>  #f
          (eqv? 2 2)                             =>  #t
          (eqv? '() '())                         =>  #t
          (eqv? 100000000 100000000)             =>  #t
          (eqv? (cons 1 2) (cons 1 2))           =>  #f
          (eqv? (lambda () 1)
                (lambda () 2))                   =>  #f
          (eqv? #f 'nil)                         =>  #f
          (let ((p (lambda (x) x)))
            (eqv? p p))                          =>  _unspecified_

     The following examples illustrate cases in which the above rules do
     not fully specify the behavior of `eqv?'.  All that can be said
     about such cases is that the value returned by `eqv?' must be a
     boolean.

          (eqv? "" "")                           =>  _unspecified_
          (eqv? '#() '#())                       =>  _unspecified_
          (eqv? (lambda (x) x)
                (lambda (x) x))                  =>  _unspecified_
          (eqv? (lambda (x) x)
                (lambda (y) y))                  =>  _unspecified_

          (define gen-counter
            (lambda ()
              (let ((n 0))
                (lambda () (set! n (+ n 1)) n))))
          (let ((g (gen-counter)))
            (eqv? g g))                          =>  #t
          (eqv? (gen-counter) (gen-counter))
                                                 =>  #f
          (define gen-loser
            (lambda ()
              (let ((n 0))
                (lambda () (set! n (+ n 1)) 27))))
          (let ((g (gen-loser)))
            (eqv? g g))                          =>  #t
          (eqv? (gen-loser) (gen-loser))
                                                 =>  _unspecified_

          (letrec ((f (lambda () (if (eqv? f g) 'both 'f)))
                   (g (lambda () (if (eqv? f g) 'both 'g))))
            (eqv? f g))
                                                 =>  _unspecified_

          (letrec ((f (lambda () (if (eqv? f g) 'f 'both)))
                   (g (lambda () (if (eqv? f g) 'g 'both))))
            (eqv? f g))
                                                 =>  #f
          (eqv? '(a) '(a))                       =>  _unspecified_
          (eqv? "a" "a")                         =>  _unspecified_
          (eqv? '(b) (cdr '(a b)))               =>  _unspecified_
          (let ((x '(a)))
            (eqv? x x))                          =>  #t


 -- library procedure: equal? obj1 obj2
          (equal? 'a 'a)                         =>  #t
          (equal? '(a) '(a))                     =>  #t
          (equal? '(a (b) c)
                  '(a (b) c))                    =>  #t
          (equal? "abc" "abc")                   =>  #t
          (equal? 2 2)                           =>  #t
          (equal? (make-vector 5 'a)
                  (make-vector 5 'a))            =>  #t
          (equal? (lambda (x) x)
                  (lambda (y) y))                =>  _unspecified_

  *Note r5rs.info: (R5RS)Equivalence predicates, for more details.


File: bigloo.info,  Node: Pairs And Lists,  Next: Symbols,  Prev: Equivalence Predicates,  Up: Scheme Library

4.1.3 Pairs and lists
---------------------

The form `()' is _illegal_.

 -- procedure: pair? obj

 -- procedure: cons a d

 -- bigloo procedure: pair-or-null? obj
     Returns `#t' if OBJ is either a pair or the empty list. Otherwise
     it returns `#f'.

 -- procedure: car pair
 -- procedure: cdr pair
 -- procedure: set-car! pair obj
 -- procedure: set-cdr! pair obj

 -- library procedure: caar pair
 -- library procedure: cadr pair
     ...

 -- library procedure: cdddar pair
 -- library procedure: cddddr pair

 -- library procedure: null? obj
 -- library procedure: list? obj
 -- library procedure: list obj ...
 -- library procedure: length list
 -- library procedure: append list ...
 -- bigloo procedure: append! list ...
     A destructive append.

 -- library procedure: reverse list
 -- bigloo procedure: reverse! list
     A destructive reverse.

 -- library procedure: list-ref list k
 -- library procedure: take list k
 -- library procedure: drop list k
 -- library procedure: list-tail list k
     `list-ref' returns the K element of the list.

     `take' returns a new list made of the first K element of the list.

     `Drop' and `list-tail' returns the sublist of LIST obtained by
     omitting the first K elements.

 -- bigloo procedure: last-pair list
     Returns the last pair in the nonempty, possibly improper, LIST.

 -- library procedure: memq obj list
 -- library procedure: memv obj list
 -- library procedure: member obj list
 -- library procedure: assq obj alist
 -- library procedure: assv obj alist
 -- library procedure: assoc obj alist
 -- bigloo procedure: remq obj list
     Returns a new list which is a copy of LIST with all items `eq?' to
     OBJ removed from it.

 -- bigloo procedure: remq! obj list
     Same as `remq' but in a destructive way.

 -- bigloo procedure: delete obj list [eq equal?]
     Returns a new list which is a copy of LIST with all items `equal?'
     to OBJ deleted from it.

 -- bigloo procedure: delete! obj list [eq equal?]
     Same as `delete' but in a destructive way.

 -- bigloo procedure: cons* obj ...
     Returns an object formed by consing all arguments together from
     right to left.  If only one OBJ is supplied, that OBJ is returned.

 -- bigloo procedure: every? fun clist1 clist2 ...
     Applies the predicate across the lists, returning true if the
     predicate returns non-false on every application.

          (every < '(1 2 3) '(2 3 4))            => #t
          (every < '(1 2 3) '(2 3 0))            => #f

 -- bigloo procedure: any? fun clist1 clist2 ...
     Applies the predicate across the lists, returning true if the
     predicate returns non-false for at least one application.

          (any < '(1 2 3) '(2 3 4))            => #t
          (any < '(1 2 3) '(2 3 0))            => #t

 -- bigloo procedure: every fun clist1 clist2 ...
     Applies the function FUN across the lists, returning the last
     non-false if the function returns non-false on every application.
     If non-false, the result of `every' is the last value returned by
     the last application of FUN.

          (every < '(1 2 3) '(2 3 4))            => #t
          (every < '(1 2 3) '(2 3 0))            => #f

 -- bigloo procedure: any fun clist1 clist2 ...
     Applies the function FUN across the lists, returning non-false if
     the function returns non-false for at least one application. If
     non-false, the result of `any' is the first non-false value
     returned by FUN.

          (any < '(1 2 3) '(2 3 4))            => #t
          (any < '(1 2 3) '(2 3 0))            => #t

 -- bigloo procedure: find pred clist
     Return the first element of CLIST that satisfies predicate PRED;
     false if no element does.

          (find even? '(3 1 4 1 5 9))          => 4

     Note that `find' has an ambiguity in its lookup semantics - if
     find returns `#f', you cannot tell (in general) if it found a `#f'
     element that satisfied PRED, or if it did not find any element at
     all. In many situations, this ambiguity cannot arise - either the
     list being searched is known not to contain any `#f' elements, or
     the list is guaranteed to have an element satisfying pred.
     However, in cases where this ambiguity can arise, you should use
     find-tail instead of find - find-tail has no such ambiguity:

              (cond ((find-tail pred lis) => (lambda (pair) ...)) ; Handle (CAR PAIR)
                    (else ...)) ; Search failed.

 -- bigloo procedure: find-tail pred clist
     Return the first pair of CLIST whose car satisfies PRED. If no
     pair does, return false.

     `find-tail' can be viewed as a general-predicate variant of the
     member function.

     Examples:

              (find-tail even? '(3 1 37 -8 -5 0 0)) => (-8 -5 0 0)
              (find-tail even? '(3 1 37 -5)) => #f

              ;; MEMBER X LIS:
              (find-tail (lambda (elt) (equal? x elt)) lis)

              In the circular-list case, this procedure "rotates" the list.

 -- bigloo procedure: make-list n [fill]
     Returns an N-element list, whose elements are all the value FILL.
     If the FILL argument is not given, the elements of the list may be
     arbitrary values.

          (make-list 4 'c)                     => (c c c c)

 -- bigloo procedure: list-tabulate n init-proc
     Returns an N-element list. Element i of the list, where 0 <= i <
     N, is produced by `(init-proc i)'. No guarantee is made about the
     dynamic order in which INIT-PROC is applied to these indices.

          (list-tabulate 4 values)             => (0 1 2 3)

 -- bigloo procedure: list-split list n [filler]
 -- bigloo procedure: list-split list n [filler]
     Split a LIST into a list of lists of length N. Last smaller list
     is filled with FILLER.

          (list-split '(1 2 3 4 5 6 7 8) 3 0) => ((1 2 3) (4 5 6) (7 8 0))
          (list-split (iota 10) 3)            => ((0 1 2) (3 4 5) (6 7 8) (9))
          (list-split (iota 10 3) '-1)      => ((0 1 2) (3 4 5) (6 7 8) (9 -1 -1))

 -- bigloo procedure: iota count [start step]
     Returns a list containing the elements

          (start start+step ... start+(count-1)*step)

     The START and STEP parameters default to `0' and `1',
     respectively. This procedure takes its name from the APL primitive.

          (iota 5) => (0 1 2 3 4)
          (iota 5 0 -0.1) => (0 -0.1 -0.2 -0.3 -0.4)

 -- bigloo procedure: list-copy l
 -- bigloo procedure: tree-copy l
     The function `list-copy' copies the spine of the of the list.  The
     function `tree-copy' recursively copies its arguments, descending
     only into the list cells.

 -- bigloo procedure: delete-duplicates list [eq equal?]
 -- bigloo procedure: delete-duplicates! list [eq equal?]
     `delete-duplicates' removes duplicate elements from the LIST
     argument. If there are multiple equal elements in the argument
     list, the result list only contains the first or leftmost of these
     elements in the result. The order of these surviving elements is
     the same as in the original list - `delete-duplicates' does not
     disorder the list (hence it is useful for "cleaning up"
     association lists).

     The EQUAL parameter is used to compare the elements of the list;
     it defaults to `equal?'. If x comes before y in list, then the
     comparison is performed (= x y). The comparison procedure will be
     used to compare each pair of elements in list no more than once;
     the order in which it is applied to the various pairs is not
     specified.

     `delete-duplicates' is allowed to share common tails between
     argument and result lists - for example, if the list argument
     contains only unique elements, it may simply return exactly this
     list.

  *Note r5rs.info: (R5RS)Pairs and lists, for more details.


File: bigloo.info,  Node: Symbols,  Next: Keywords,  Prev: Pairs And Lists,  Up: Scheme Library

4.1.4 Symbols
-------------

Symbols are case sensitive and the reader is case sensitive too. So:
     (eq? 'foo 'FOO) => #f
     (eq? (string->symbol "foo") (string->symbol "FOO")) => #f

  Symbols may contain special characters (such as #\Newline or #\Space).
Such symbols that have to be read must be written: `|[^]+|'. The
function `write' uses that notation when it encounters symbols
containing special characters.

     (write 'foo) => foo
     (write 'Foo) =>Foo
     (write '|foo bar|) => |foo bar|

 -- procedure: symbol? obj
 -- procedure: symbol->string symbol
     Returns the name of the symbol as a string. Modifying the string
     result of `symbol->string' could yield incoherent programs. It is
     better to copy the string before any physical update. For
     instance, don't write:
          (string-downcase! (symbol->string 'foo))

     *Note r5rs.info: (R5RS)Symbols, for more details.

     but prefer:
          (string-downcase (symbol->string 'foo))

 -- procedure: string->symbol string
 -- bigloo procedure: string->symbol-ci string
 -- bigloo procedure: symbol-append symbol ...
     `String->symbol' returns a symbol whose name is STRING.
     `String->symbol' respects the case of STRING.  `String->symbol-ci'
     returns a symbol whose name is `(string-upcase STRING)'.
     `Symbol-append' returns a symbol whose name is the concatenation
     of all the SYMBOL's names.

 -- bigloo procedure: gensym [obj]
     Returns a new fresh symbol. If OBJ is provided and is a string or
     a symbol, it is used as prefix for the new symbol.

 -- bigloo procedure: symbol-plist symbol-or-keyword
     Returns the property-list associated with SYMBOL-OR-KEYWORD.

 -- bigloo procedure: getprop symbol-or-keyword key
     Returns the value that has the key `eq?' to KEY from the
     SYMBOL-OR-KEYWORD's property list. If there is no value associated
     with KEY then `#f' is returned.

 -- bigloo procedure: putprop! symbol-or-keyword key val
     Stores VAL using KEY on SYMBOL-OR-KEYWORD's property list.

 -- bigloo procedure: remprop! symbol-or-keyword key
     Removes the value associated with KEY in the SYMBOL-OR-KEYWORD's
     property list. The result is unspecified.

  Here is an example of properties handling:

     (getprop 'a-sym 'a-key)       => #f
     (putprop! 'a-sym 'a-key 24)
     (getprop 'a-sym 'a-key)       => 24
     (putprop! 'a-sym 'a-key2 25)
     (getprop 'a-sym 'a-key)       => 24
     (getprop 'a-sym 'a-key2)      => 25
     (symbol-plist 'a-sym)         => (a-key2 25 a-key 24)
     (remprop! 'a-sym 'a-key)
     (symbol-plist 'a-sym)         => (a-key2 25)
     (putprop! 'a-sym 'a-key2 16)
     (symbol-plist 'a-sym)         => (a-key2 16)


File: bigloo.info,  Node: Keywords,  Next: Numbers,  Prev: Symbols,  Up: Scheme Library

4.1.5 Keywords
--------------

Keywords constitute an extension to Scheme required by Dsssl [Dsssl96].
Keywords syntax is either `<ident>:' or `:<ident>'.

  Keywords are autoquote and case sensitive. So
     (eq? toto: TOTO:) => #f

  The colon character (`:') does not belong to they keyword. Hence
     (eq? toto: :toto) => #t

 -- bigloo procedure: keyword? obj
 -- bigloo procedure: keyword->string keyword
 -- bigloo procedure: string->keyword string
 -- bigloo procedure: keyword->symbol keyword
 -- bigloo procedure: symbol->keyword symbol


File: bigloo.info,  Node: Numbers,  Next: Characters,  Prev: Keywords,  Up: Scheme Library

4.1.6 Numbers
-------------

Bigloo has only three kinds of numbers: fixnum, long fixnum and flonum.
Operations on complexes and rationals are not implemented but for
compatibility purposes, the functions `complex?' and `rational?' exist.
(In fact, `complex?' is the same as `number?' and `rational?'  is the
same as `real?' in Bigloo.) The accepted prefixes are `#b', `#o', `#d',
`#x', `#e', `#ex', `#l', `#lx', and `#z'.  For each generic arithmetic
procedure, Bigloo provides two specialized procedures, one for fixnums
and one for flonums. The names of these two specialized procedures is
the name of the original one suffixed by `fx' (fixnum), `fl' (flonum),
`elong' (exact C long), `llong' (exact C long long), and `bx' (big
integer).  A fixnum has the size of a C `long' minus 2 bits. A flonum
has the size of a C `double'. An elong has the size of a C long. An
llong has the size of a C long long. A big integer has an unbounded
size.

 -- procedure: number? obj
 -- procedure: real? obj
 -- procedure: integer? obj
 -- bigloo procedure: complex? x
 -- bigloo procedure: rational? x

 -- bigloo procedure: fixnum? obj
 -- bigloo procedure: flonum? obj
     These two procedures are type checkers on types `integer' and
     `real'.

 -- bigloo procedure: elong? obj
 -- bigloo procedure: llong? obj
     The `elong?' procedures is a type checker for "hardware" integers,
     that is integers that have the very same size has the host
     platform permits (e.g., 32 bits or 64 bits integers). The `llong?'
     procedure is a type checker for "hardware" long long integers.
     Exact integers literal are introduced with the special `#e' and
     `#ex' prefixes. Exact long integers literal are introduced with
     the special `#l' and `#lx' prefixes.

 -- bigloo procedure: bignum? obj
     This type checker tests if its argument is a big integer.

 -- bigloo procedure: make-elong int
 -- bigloo procedure: make-llong int
     Create an exact fixnum integer from the fixnum value INT.

 -- bigloo procedure: minvalfx
 -- bigloo procedure: maxvalfx
 -- bigloo procedure: minvalelong
 -- bigloo procedure: maxvalelong
 -- bigloo procedure: minvalllong
 -- bigloo procedure: maxvalllong
     Returns the minimal value (respectively the maximal value) for fix
     integers.

 -- procedure: exact? z
 -- procedure: inexact? z

 -- library procedure: zero? z
 -- library procedure: positive? z
 -- library procedure: negative? z
 -- library procedure: odd? n
 -- library procedure: even? n
 -- library procedure: zerofx? z
 -- library procedure: positivefx? z
 -- library procedure: negativefx? z
 -- library procedure: oddfx? n
 -- library procedure: evenfx? n
 -- library procedure: zerofl? z
 -- library procedure: positivefl? z
 -- library procedure: negativefl? z
 -- library procedure: oddfl? n
 -- library procedure: evenfl? n
 -- library procedure: zeroelong? z
 -- library procedure: positiveelong? z
 -- library procedure: negativeelong? z
 -- library procedure: oddelong? n
 -- library procedure: evenelong? n
 -- library procedure: zerollong? z
 -- library procedure: positivellong? z
 -- library procedure: negativellong? z
 -- library procedure: oddllong? n
 -- library procedure: evenllong? n
 -- library procedure: zerobx? z
 -- library procedure: positivebx? z
 -- library procedure: negativebx? z
 -- library procedure: oddbx? n
 -- library procedure: evenbx? n

 -- library procedure: min x1 x2 ...
 -- library procedure: max x1 x2 ...
 -- bigloo procedure: minfx x1 x2 ...
 -- bigloo procedure: maxfx x1 x2 ...
 -- bigloo procedure: minfl x1 x2 ...
 -- bigloo procedure: maxfl x1 x2 ...
 -- bigloo procedure: minbx x1 x2 ...
 -- bigloo procedure: maxbx x1 x2 ...

 -- procedure: = z1 z2 z3 ...
 -- bigloo procedure: =fx i1 i2
 -- bigloo procedure: =fl r1 r2
 -- bigloo procedure: =elong r1 r2
 -- bigloo procedure: =llong r1 r2
 -- bigloo procedure: =bx r1 r2
 -- procedure: < z1 z2 z3 ...
 -- bigloo procedure: <fx i1 i2
 -- bigloo procedure: <fl r1 r2
 -- bigloo procedure: <elong r1 r2
 -- bigloo procedure: <lllong r1 r2
 -- bigloo procedure: <bx r1 r2
 -- procedure: > z1 z2 z3 ...
 -- bigloo procedure: >fx i1 i2
 -- bigloo procedure: >fl r1 r2
 -- bigloo procedure: >elong r1 r2
 -- bigloo procedure: >lllong r1 r2
 -- bigloo procedure: >bx r1 r2
 -- procedure: <= z1 z2 z3 ...
 -- bigloo procedure: <=fx i1 i2
 -- bigloo procedure: <=fl r1 r2
 -- bigloo procedure: <=elong r1 r2
 -- bigloo procedure: <=llong r1 r2
 -- bigloo procedure: <=bx r1 r2
 -- procedure: >= z1 z2 z3 ...
 -- bigloo procedure: >=fx i1 i2
 -- bigloo procedure: >=fl r1 r2
 -- bigloo procedure: >=elong r1 r2
 -- bigloo procedure: >=llong r1 r2
 -- bigloo procedure: >=bx r1 r2

 -- procedure: + z ...
 -- bigloo procedure: +fx i1 i2
 -- bigloo procedure: +fl r1 r2
 -- bigloo procedure: +elong r1 r2
 -- bigloo procedure: +llong r1 r2
 -- bigloo procedure: +bx r1 r2
 -- procedure: * z ...
 -- bigloo procedure: *fx i1 i2
 -- bigloo procedure: *fl r1 r2
 -- bigloo procedure: *elong r1 r2
 -- bigloo procedure: *llong r1 r2
 -- bigloo procedure: *bx r1 r2
 -- procedure: - z
 -- procedure: - z1 z2 ...
 -- bigloo procedure: -fx i1 i2
 -- bigloo procedure: -fl r1 r2
 -- bigloo procedure: -elong r1 r2
 -- bigloo procedure: -llong r1 r2
 -- bigloo procedure: -bx r1 r2
 -- bigloo procedure: negfx i
 -- bigloo procedure: negfl r
 -- bigloo procedure: negelong r
 -- bigloo procedure: negllong r
 -- bigloo procedure: negbx r
     These two functions implement the unary function `-'.

 -- procedure: / z1 z2
 -- procedure: / z1 z2 ...
 -- bigloo procedure: /fx i1 i2
 -- bigloo procedure: /fl r1 r2
 -- bigloo procedure: /elong r1 r2
 -- bigloo procedure: /llong r1 r2
 -- bigloo procedure: /bx r1 r2

 -- library procedure: abs z
 -- bigloo procedure: absfl z
 -- procedure: quotient z1 z2
 -- procedure: quotientelong z1 z2
 -- procedure: quotientllong z1 z2
 -- procedure: remainder z1 z2
 -- procedure: remainderelong z1 z2
 -- procedure: remainderllong z1 z2
 -- procedure: remainderfl z1 z2
 -- procedure: modulo z1 z2
 -- procedure: gcd z ...
 -- procedure: lcm z ...
 -- procedure: floor z
 -- procedure: floorfl z
 -- procedure: ceiling z
 -- procedure: ceilingfl z
 -- procedure: truncate z
 -- procedure: truncatefl z
 -- procedure: round z
 -- procedure: roundfl z

 -- bigloo procedure: random z
 -- bigloo procedure: seed-random! z
     the `random' function returns a pseudo-random integer between 0
     and Z.

     If no seed value is provided,  the `random' function  is
     automatically seeded with a value of 1.

 -- procedure: exp z
 -- procedure: expfl z
 -- procedure: log z
 -- procedure: logfl z
 -- procedure: sin z
 -- procedure: sinfl z
 -- procedure: cos z
 -- procedure: cosfl z
 -- procedure: tan z
 -- procedure: tanfl z
 -- procedure: asin z
 -- procedure: asinfl z
 -- procedure: acos z
 -- procedure: acosfl z
 -- procedure: atan z1 z2
 -- procedure: atanfl z1 z2
 -- procedure: sqrt z
 -- procedure: sqrtfl z
 -- procedure: expt z1 x2
 -- procedure: exptfl z1 x2

 -- procedure: exact->inexact z
 -- procedure: inexact->exact z
 -- procedure: number->string z
 -- bigloo procedure: integer->string i [radix 10]
 -- bigloo procedure: integer->string/padding i padding [radix 10]
 -- bigloo procedure: elong->string i [radix 10]
 -- bigloo procedure: llong->string i [radix 10]
 -- bigloo procedure: real->string z
 -- bigloo procedure: unsigned->string i [radix 16]
     The function `integer->string/padding' converts its arguments into
     a string with a left padding filled of characters `0'.

          (integer->string/padding 3 5)       => "00003"

     The function `unsigned->string' only accepts the following radixes:
     `2', `8', and `16'. It converts its argument into an _unsigned_
     representation.

          (unsigned->string 123 16)           => "7b"
          (unsigned->string -123 16)          => "ffffff85"


 -- procedure: string->number string [radix 10]
 -- bigloo procedure: string->real string
 -- bigloo procedure: string->elong string radix
 -- bigloo procedure: string->llong string radix
 -- bigloo procedure: string->bignum string radix
     Bigloo implements a restricted version of `string->number'. If
     STRING denotes a floating point number then, the only radix `10'
     may be send to `string->number'. That is:

          (string->number "1243" 16)          => 4675
          (string->number "1243.0" 16)        -|
          # *** ERROR:bigloo:string->number
          # Only radix `10' is legal for floating point number -- 16
          (string->elong "234456353")         => #e234456353

     In addition, `string->number' does not support radix encoded inside
     STRING. That is:

          (string->number "#x1243")          => #f

 -- bigloo procedure: fixnum->flonum i
 -- bigloo procedure: flonum->fixnum r
 -- bigloo procedure: elong->fixnum i
 -- bigloo procedure: fixnum->elong r
 -- bigloo procedure: llong->fixnum i
 -- bigloo procedure: fixnum->llong r
 -- bigloo procedure: elong->flonum i
 -- bigloo procedure: flonum->elong r
 -- bigloo procedure: llong->flonum i
 -- bigloo procedure: flonum->llong r
     For efficiency, `string->real' and `string->integer' do not test
     whether the string can be read as a number.  Therefore the result
     might be wrong if the string cannot be read as a number.

     These last procedures implement the natural translation from and
     to fixnum, flonum, elong, and llong.


  *Note r5rs.info: (R5RS)Numerical operations, for more details.


File: bigloo.info,  Node: Characters,  Next: UCS-2 Characters,  Prev: Numbers,  Up: Scheme Library

4.1.7 Characters
----------------

Bigloo knows one more named characters `#\tab', `#\return', and
`#\null' in addition to the `#\space' and `#\newline' of R5RS.

  A new alternate syntax exists for characters: `#a<ascii-code>' where
`<ascii-code>' is the three digit decimal ascii number of the character
to be read. Thus, for instance, the character `#\space' can be written
`#a032'.

 -- procedure: char? obj

 -- procedure: char=? char1 char2
 -- procedure: char<? char1 char2
 -- procedure: char>? char1 char2
 -- procedure: char<=? char1 char2
 -- procedure: char>=? char1 char2
 -- library procedure: char-ci=? char1 char2
 -- library procedure: char-ci<? char1 char2
 -- library procedure: char-ci>? char1 char2
 -- library procedure: char-ci<=? char1 char2
 -- library procedure: char-ci>=? char1 char2

 -- library procedure: char-alphabetic? char
 -- library procedure: char-numeric? char
 -- library procedure: char-whitespace? char
 -- library procedure: char-upper-case? char
 -- library procedure: char-lower-case? char

 -- procedure: char->integer char
 -- procedure: integer->char i

 -- library procedure: char-upcase char
 -- library procedure: char-downcase char


File: bigloo.info,  Node: UCS-2 Characters,  Next: Strings,  Prev: Characters,  Up: Scheme Library

4.1.8 UCS-2 Characters
----------------------

UCS-2 Characters are two byte encoded characters. They can be read with
the syntax: `#u<unicode>' where `<unicode>' is the four digit
hexadecimal unicode value of the character to be read. Thus, for
instance, the character `#\space' can be written `#u0020'.

 -- bigloo procedure: ucs2? obj

 -- bigloo procedure: ucs2=? ucs2a ucs2b
 -- bigloo procedure: ucs2<? ucs2a ucs2b
 -- bigloo procedure: ucs2>? ucs2a ucs2b
 -- bigloo procedure: ucs2<=? ucs2a ucs2b
 -- bigloo procedure: ucs2>=? ucs2a ucs2b
 -- bigloo procedure: ucs2-ci=? ucs2a ucs2b
 -- bigloo procedure: ucs2-ci<? ucs2a ucs2b
 -- bigloo procedure: ucs2-ci>? ucs2a ucs2b
 -- bigloo procedure: ucs2-ci<=? ucs2a ucs2b
 -- bigloo procedure: ucs2-ci>=? ucs2a ucs2b

 -- bigloo procedure: ucs2-alphabetic? ucs2
 -- bigloo procedure: ucs2-numeric? ucs2
 -- bigloo procedure: ucs2-whitespace? ucs2
 -- bigloo procedure: ucs2-upper-case? ucs2
 -- bigloo procedure: ucs2-lower-case? ucs2

 -- bigloo procedure: ucs2->integer ucs2
 -- bigloo procedure: integer->ucs2 i

 -- bigloo procedure: ucs2->char ucs2
 -- bigloo procedure: char->ucs2 char

 -- bigloo procedure: ucs2-upcase ucs2
 -- bigloo procedure: ucs2-downcase ucs2


File: bigloo.info,  Node: Strings,  Next: Unicode (UCS-2) Strings,  Prev: UCS-2 Characters,  Up: Scheme Library

4.1.9 Strings
-------------

There are three different syntaxes for strings in Bigloo: traditional,
foreign or Unicode. The traditional syntax for strings may conform to
the Revised Report, see *note r5rs.info: (R5RS)Lexical structure.  With
the foreign syntax, C escape sequences are interpreted as specified by
ISO-C. In addition, Bigloo's reader evaluate `\x??' sequence as an
hexadecimal escape character. For Unicode syntax, see *note Unicode
(UCS-2) Strings::. Only the reader distinguishes between these three
appearances of strings; i.e., there is only one type of string at
evaluation-time. The regular expression describing the syntax for
foreign string is: `#"([^"]|\")*"'. Escape characters are controlled by
the parameter `bigloo-strict-r5rs-strings' (see *note Parameters::).

  The library functions for string processing are:

 -- procedure: string? obj

 -- SRFI-13 procedure: string-null? s
     Is S an empty string?

 -- procedure: make-string k
 -- procedure: make-string k char
 -- library procedure: string char ...

 -- procedure: string-length string
 -- procedure: string-ref string k
 -- procedure: string-set! string k char

 -- library procedure: string=? string1 string2
     This function returns `#t' if the STRING1 and STRING2 are made of
     the same characters. It returns `#f' otherwise.

 -- bigloo procedure: substring=? string1 string2 len
     This function returns `#t' if STRING1 and STRING2 have a common
     prefix of size LEN.

          (substring=? "abcdef" "ab9989898" 2)
             => #t
          (substring=? "abcdef" "ab9989898" 3)
             => #f

 -- bigloo procedure: substring-at? string1 string2 offset [len]
 -- bigloo procedure: substring-ci-at? string1 string2 offset [len]
     This function returns `#t' if STRING2 is at position OFFSET in the
     string `string1'. It returns `#f' otherwise.
          (substring-at? "abcdefghij" "def" 3)
             => #t
          (substring-at? "abcdefghij" "def" 2)
             => #f
          (substring-at? "abcdefghij" "defz" 3)
             => #f
          (substring-at? "abcdefghij" "defz" 3 3)
             => #t

 -- library procedure: string-ci=? string1 string2
 -- bigloo procedure: substring-ci=? string1 string2 len
 -- bigloo procedure: substring-ci-at? string1 string2 pos
 -- library procedure: string<? string1 string2
 -- library procedure: string>? string1 string2
 -- library procedure: string<=? string1 string2
 -- library procedure: string>=? string1 string2
 -- library procedure: string-ci<? string1 string2
 -- library procedure: string-ci>? string1 string2
 -- library procedure: string-ci<=? string1 string2
 -- library procedure: string-ci>=? string1 string2

 -- bigloo procedure: string-index string charset [start 0]
 -- bigloo procedure: string-index-right string charset [start len-1]
     Returns the first occurrence of a character of CHAR-OR-SET in
     STRING. The argument CHARSET is either a character or a string.
     If no character is found, `string-index' returns `#f'.

 -- bigloo procedure: string-contains string1 string2 [start 0]
 -- bigloo procedure: string-contains-ci string1 string2 [start 0]
     Does string s1 contain string s2?

     Return the index in STRING1 where STRING2 occurs first as a
     substring, or false.

     `string-contains-ci' is the case-insensitive variant.
     Case-insensitive comparison is done by case-folding characters
     with the operation:

          (char-downcase (char-upcase c))

 -- bigloo procedure: string-compare3 string1 string2
 -- bigloo procedure: string-compare3-ci string1 string2
     This function compares STRING1 and STRING2. It returns a negative
     integer if STRING1 < STRING2. It returns zero if the STRING1 equal
     STRING2. It returns a positive integer if STRING1 > STRING2.

 -- bigloo procedure: string-natural-compare3 string1 string2
 -- bigloo procedure: string-natural-compare3-ci string1 string2
     This function compares STRING1 and STRING2 according to a _natural
     string order_. It returns a negative integer if STRING1 < STRING2.
     It returns zero if the STRING1 equal STRING2. It returns a
     positive integer if STRING1 > STRING2.

          (string-natural-compare "foo" "foo")
             => 0
          (string-natural-compare "foo0" "foo1")
             => -1
          (string-natural-compare "foo1" "foo0")
             => 1
          (string-natural-compare "rfc822.txt" "rfc1.txt")
             => -1
          (string-natural-compare "rfc1.txt" "rfc2086.txt")
             => -1
          (string-natural-compare "rfc2086.txt" "rfc1.txt")
             => 1
          (string-natural-compare "rfc822.txt" "rfc2086.txt")
             => -1
          (string-natural-compare "a0" "a1")
             => -1
          (string-natural-compare "a1" "a1a")
             => -1
          (string-natural-compare "a1a" "a1b")
             => -1
          (string-natural-compare "a1b" "a2")
             => -1
          (string-natural-compare "a2" "a10")
             => -1
          (string-natural-compare "a10" "a20")
             => -1
          (string-natural-compare "a2" "a20")
             => -1
          (string-natural-compare "x2-g8" "x2-y7")
             => -1
          (string-natural-compare "1.001" "1.002")
             => -1
          (string-natural-compare "1.002" "1.010")
             => -1
          (string-natural-compare "1.010"  "1.02")
             => 1
          (string-natural-compare "1.02" "1.1")
             => -1
          (string-natural-compare "1.1" "1.02")
             => 1
          (string-natural-compare "1.02" "1.3")
             => -1

 -- library procedure: substring string start end
     STRING must be a string, and START and END must be exact integers
     satisfying:

            0 <= START <= END <= (string-length STRING)

     `substring' returns a newly allocated string formed from the
     characters of STRING beginning with index START (inclusive) and
     ending with index END (exclusive).

          (substring "abcdef" 0 5)
             => "abcde"
          (substring "abcdef" 1 5)
             => "bcde"

 -- library procedure: string-shrink! string end
     STRING must be a string, and END must be an exact integers
     satisfying:

            0 <= END <= (string-length STRING)

     `string-shrink!' returns a newly allocated string formed from the
     characters of STRING beginning with index 0 (inclusive) and ending
     with index END (exclusive). As much as possible `string-shrink!'
     changes the argument STRING. That is, as much as possible, and for
     the back-ends that enable it, STRING-SHRINK!  operate a side
     effect on its argument.

          (let ((s (string #\a #\b #\c #\d #\e)))
             (set! s (string-shrink! s 3))
             s)
             => "abc"

 -- library procedure: string-append string ...
 -- library procedure: string->list string
 -- library procedure: list->string list
 -- library procedure: string-copy string

 -- bigloo procedure: string-fill! string char
     Stores CHAR in every element of the given STRING and returns an
     unspecified value.

 -- bigloo procedure: string-downcase string
     Returns a newly allocated version of string where each upper case
     letter is replaced by its lower case equivalent.

 -- bigloo procedure: string-upcase string
     Returns a newly allocated version of string where each lower case
     letter is replaced by its upper case equivalent.

 -- bigloo procedure: string-capitalize string
     Builds a newly allocated capitalized string.

 -- bigloo procedure: string-downcase! string
     Physically downcases the STRING argument.

 -- bigloo procedure: string-upcase! string
     Physically upcases the STRING argument.

 -- bigloo procedure: string-capitalize! string
     Physically capitalized the STRING argument.

 -- bigloo procedure: string-for-read string
     Returns a copy of STRING with each special character replaced by
     an escape sequence.

 -- bigloo procedure: blit-string! string1 o1 string2 o2 len
     Fill string S2 starting at position O2 with LEN characters taken
     out of string S1 from position O1.

          (let ((s (make-string 20 #\-)))
          	(blit-string! "toto" 0 s 16 4)
          	s)
             => "----------------toto"

 -- bigloo procedure: string-replace string char1 char2
 -- bigloo procedure: string-replace! string char1 char2
     Replace all the occurrence of CHAR1 by CHAR2 in STRING.  The
     function `string-replace' returns a newly allocated string.  The
     function `string-replace!' modifies its first argument.

 -- bigloo procedure: string-split string
 -- bigloo procedure: string-split string delimiters
     Parses STRING and returns a list of tokens ended by a character of
     the DELIMITERS string. If DELIMITERS is omitted, it defaults to a
     string containing a space, a tabulation and a newline characters.

          (string-split "/usr/local/bin" "/") => ("usr" "local" "bin")
          (string-split "once   upon a time") => ("once" "upon" "a" "time")

 -- SRFI-13 procedure: string-prefix-length s1 s2 [start1 end1 start2
          end2]
 -- SRFI-13 procedure: string-suffix-length s1 s2 [start1 end1 start2
          end2]
 -- SRFI-13 procedure: string-prefix-length-ci s1 s2 [start1 end1
          start2 end2]
 -- SRFI-13 procedure: string-suffix-length-ci s1 s2 [start1 end1
          start2 end2]
     Return the length of the longest common prefix/suffix of the two
     strings. For prefixes, this is equivalent to the "mismatch index"
     for the strings (modulo the starti index offsets).

     The optional start/end indices restrict the comparison to the
     indicated substrings of s1 and s2.

 -- SRFI-13 procedure: string-prefix? s1 s2 [start1 end1 start2 end2]
 -- SRFI-13 procedure: string-suffix? s1 s2 [start1 end1 start2 end2]
 -- SRFI-13 procedure: string-prefix-ci? s1 s2 [start1 end1 start2 end2]
 -- SRFI-13 procedure: string-suffix-ci? s1 s2 [start1 end1 start2 end2]
     Is s1 a prefix/suffix of s2?

     The optional start/end indices restrict the comparison to the
     indicated substrings of s1 and s2.


 -- bigloo procedure: string-hex-intern string
 -- bigloo procedure: string-hex-intern! string
     Converts an hexadecimal STRING of `n' characters into an actual
     string of `n/2' characters.

          (string-hex-intern "4a4b4c") => "JKL"

 -- bigloo procedure: string-hex-extern string
     Converts a STRING into a hexadecimal representation.

          (string-hex-extern "JKL") => "4a4b4c"



File: bigloo.info,  Node: Unicode (UCS-2) Strings,  Next: Vectors,  Prev: Strings,  Up: Scheme Library

4.1.10 Unicode (UCS-2) Strings
------------------------------

UCS-2 strings cannot be read by the standard reader but UTF-8 strings
can. The special syntax for UTF-8 is described by the regular
expression: `#u"([^]|\")*"'.

  The library functions for Unicode string processing are:

 -- bigloo procedure: ucs2-string? obj

 -- bigloo procedure: make-ucs2-string k
 -- bigloo procedure: make-ucs2-string k char
 -- bigloo procedure: ucs2-string k ...

 -- bigloo procedure: ucs2-string-length s-ucs2
 -- bigloo procedure: ucs2-string-ref s-ucs2 k
 -- bigloo procedure: ucs2-string-set! s-ucs2 k char

 -- bigloo procedure: ucs2-string=? s-ucs2a s-ucs2b
 -- bigloo procedure: ucs2-string-ci=? s-ucs2a s-ucs2b
 -- bigloo procedure: ucs2-string<? s-ucs2a s-ucs2b
 -- bigloo procedure: ucs2-string>? s-ucs2a s-ucs2b
 -- bigloo procedure: ucs2-string<=? s-ucs2a s-ucs2b
 -- bigloo procedure: ucs2-string>=? s-ucs2a s-ucs2b
 -- bigloo procedure: ucs2-string-ci<? s-ucs2a s-ucs2b
 -- bigloo procedure: ucs2-string-ci>? s-ucs2a s-ucs2b
 -- bigloo procedure: ucs2-string-ci<=? s-ucs2a s-ucs2b
 -- bigloo procedure: ucs2-string-ci>=? s-ucs2a s-ucs2b

 -- bigloo procedure: subucs2-string s-ucs2 start end
 -- bigloo procedure: ucs2-string-append s-ucs2 ...
 -- bigloo procedure: ucs2-string->list s-ucs2
 -- bigloo procedure: list->ucs2-string chars
 -- bigloo procedure: ucs2-string-copy s-ucs2

 -- bigloo procedure: ucs2-string-fill! s-ucs2 char
     Stores CHAR in every element of the given s-ucs2 and returns an
     unspecified value.

 -- bigloo procedure: ucs2-string-downcase s-ucs2
     Builds a newly allocated ucs2-string with lower case letters.

 -- bigloo procedure: ucs2-string-upcase s-ucs2
     Builds a new allocated ucs2-string with upper case letters.

 -- bigloo procedure: ucs2-string-downcase! s-ucs2
     Physically downcases the S-UCS2 argument.

 -- bigloo procedure: ucs2-string-upcase! s-ucs2
     Physically upcases the S-UCS2 argument.

 -- bigloo procedure: ucs2-string->utf8-string s-ucs2
 -- bigloo procedure: utf8-string->ucs2-string STRING
     Convert UCS-2 strings to (or from) UTF-8 encoded ascii strings.

 -- bigloo procedure: iso-latin->utf8 string
 -- bigloo procedure: iso-latin->utf8! string
 -- bigloo procedure: utf8->iso-latin STRING
 -- bigloo procedure: utf8->iso-latin! STRING
     Encode and decode iso-latin strings into utf8. The functions
     `iso-latin->utf8-string!' and `utf8->iso-latin!' may return, as
     result, the string they receive as argument.


File: bigloo.info,  Node: Vectors,  Next: Homogeneous Vectors (SRFI-4),  Prev: Unicode (UCS-2) Strings,  Up: Scheme Library

4.1.11 Vectors
--------------

Vectors are not autoquoted objects.

 -- procedure: vector? obj

 -- procedure: make-vector k
 -- procedure: make-vector k obj
 -- library procedure: vector obj ...

 -- procedure: vector-length vector
 -- procedure: vector-ref vector k
 -- procedure: vector-set! vector k obj

 -- library procedure: vector->list vector
 -- library procedure: list->vector list

 -- library procedure: vector-fill! vector obj
     Stores  OBJ in every element of VECTOR. For instance:

          (let ((v (make-vector 5 #f)))
             (vector-fill! v #t)
             v)

 -- bigloo procedure: copy-vector vector len
     Allocate a new vector of size LEN and fills it with the first LEN
     element of VECTOR. The new length LEN may be bigger than the old
     vector length.

 -- bigloo procedure: vector-copy vector start end
     VECTOR must be a vector, and START and END must be exact integers
     satisfying:

            0 <= START <= END <= (vector-length VECTOR)

     `vector-copy' returns a newly allocated vector formed from the
     elements of VECTOR beginning with index START (inclusive) and
     ending with index END (exclusive).

          (vector-copy '#(1 2 3 4) 0 4)
             => '#(1 2 3 4)
          (vector-copy '#(1 2 3 4) 1 3)
             => '#(2 3)

 -- bigloo procedure: vector-copy! target tstart source [sstart [send]]
     Copies a block of elements from SOURCE to TARGET, both of which
     must be vectors, starting in target at TSTART and starting in
     source at SSTART, ending when SEND - SSTART elements have been
     copied. It is an error for TARGET to have a length less than
     `tstart + (send - sstart)'. SSTART defaults to `0' and SEND
     defaults to the length of SOURCE.

  *Note r5rs.info: Vectors, for more details.


File: bigloo.info,  Node: Homogeneous Vectors (SRFI-4),  Next: Control Features,  Prev: Vectors,  Up: Scheme Library

4.1.12 Homogeneous Vectors (SRFI-4)
-----------------------------------

Bigloo fully supports SRFI-4 specification of homogeneous vectors (see
`http://srfi.schemers.org/srfi-4/srfi-4.html').

  Each homogeneous vector is represented by a Bigloo type. That is:

   * `::s8vector' signed exact integer in the range -(2^7) to (2^7)-1

   * `::u8vector' unsigned exact integer in the range 0 to (2^8)-1

   * `::s16vector' signed exact integer in the range -(2^15) to (2^15)-1

   * `::u16vector' unsigned exact integer in the range 0 to (2^16)-1

   * `::s32vector' signed exact integer in the range -(2^31) to (2^31)-1

   * `::u32vector' unsigned exact integer in the range 0 to (2^32)-1

   * `::s64vector' signed exact integer in the range -(2^63) to (2^63)-1

   * `::u64vector' unsigned exact integer in the range 0 to (2^64)-1

   * `f32vector' inexact small real

   * `f64vector' inexact largest real


  Each homogeneous vector datatype has an external representation which
is supported by the read and write procedures and by the program
parser. Each datatype also has a set of associated predefined
procedures analogous to those available for Scheme's heterogeneous
vectors.

  As noted by Marc Feeley's specification, for each value of TAG in {
s8, u8, s16, u16, s32, u32, s64, u64, f32,f64 }, if the datatype
TAGvector is supported, then

   * the external representation of instances of the datatype TAGvector
     is  #TAG( ...elements... ).

     For example, `#u8(0 #e1e2 #xff)' is an u8vector of length 3
     containing 0, 100 and 255; `#f64(-1.5)' is an f64vector of length
     1 containing -1.5.

     Note that the syntax for float vectors conflicts with Standard
     Scheme which parses `#f32()' as 3 objects: `#f', `32' and `()'.
     For this reason, conformance to this SRFI implies this minor
     nonconformance to Standard Scheme.

     This external representation is also available in program source
     code. For example, `(set! x '#u8(1 2 3))' will set x to the object
     `#u8(1 2 3)'. Literal homogeneous vectors must be quoted just like
     heterogeneous vectors must be. Homogeneous vectors can appear in
     quasiquotations but must not contain unquote or unquote-splicing
     forms (i.e. ``(,x #u8(1 2))' is legal but ``#u8(1 ,x 2)' is not).
     This restriction is to accomodate the many Scheme systems that use
     the read procedure to parse programs.

   * the following predefined procedures are available:

      -- SRFI-4 procedure: TAGvector? obj
      -- SRFI-4 procedure: make-TAGvector n [ TAGvalue ]
      -- SRFI-4 procedure: TAGvector TAGvalue ...
      -- SRFI-4 procedure: TAGvector-length TAGvect
      -- SRFI-4 procedure: TAGvector-ref TAGvect i
      -- SRFI-4 procedure: TAGvector-set! TAGvect i TAGvalue
      -- SRFI-4 procedure: TAGvector->list TAGvect
      -- SRFI-4 procedure: list->TAGvector TAGlist
          where obj is any Scheme object, n is a nonnegative exact
          integer, i is a nonnegative exact integer less than the
          length of the vector, TAGvect is an instance of the TAGvector
          datatype, TAGvalue is a number of the type acceptable for
          elements of the TAGvector datatype, and TAGlist is a proper
          list of numbers of the type acceptable for elements of the
          TAGvector datatype.

          It is an error if TAGvalue is not the same type as the
          elements of the TAGvector datatype (for example if an exact
          integer is passed to f64vector). If the fill value is not
          specified, the content of the vector is unspecified but
          individual elements of the vector are guaranteed to be in the
          range of values permitted for that type of vector.



File: bigloo.info,  Node: Control Features,  Prev: Homogeneous Vectors (SRFI-4),  Up: Scheme Library

4.1.13 Control features
-----------------------

 -- procedure: procedure? obj

 -- procedure: apply proc arg1 ... args

 -- library procedure: map proc list1 list2 ...
 -- bigloo procedure: map! proc list1 list2 ...
 -- library procedure: for-each proc list1 list2 ...

 -- library procedure: filter pred list ...
 -- library procedure: filter! pred list ...
     Strip out all elements of LIST for which the predicate PRED is not
     true. The second version `filter!' is destructive:

          (filter number? '(1 2 #\a "foo" foo 3)) => (1 2 3)
          (let ((l (list 1 2 #\a "foo" 'foo 3)))
             (set! l (filter! number? l))
             l)                                   => (1 2 3)

 -- library procedure: append-map proc list1 list2 ...
 -- library procedure: append-map! proc list1 list2 ...
     The expression
            (append-map f clist1 clist2 ...)

     is equivalent to:

            (apply append (map f clist1 clist2 ...))

     The expression
            (append-map! f clist1 clist2 ...)

     is equivalent to:

            (apply append! (map f clist1 clist2 ...))

 -- bigloo procedure: filter-map pred list ...
     As `map' but only none `#f' values are accumulated in the resulting
     list. The Bigloo implementation complies with the SRFI-1
     description.

          (filter-map (lambda (x) (if (number? x) '- #f)) '(1 2 #\a "foo" foo 3)) => (- - -)

 -- bigloo procedure: sort proc obj
 -- bigloo procedure: sort obj proc
     Sorts OBJ according to PROC test. The argument OBJ can either be a
     vector or a list. In either case, a copy of the argument is
     returned. For instance:

          (let ((l '(("foo" 5) ("bar" 6) ("hux" 1) ("gee" 4))))
             (sort (lambda (x y) (string<? (car x) (car y))) l))
             => ((bar 6) (foo 5) (gee 4) (hux 1))

     The second form (which uses OBJ before PROC ensures backward
     compatibility with old Lisp systems, and older Bigloo versions. It
     is deprecated.

 -- library procedure: force promise

 -- bigloo procedure: call/cc proc
     This function is the same as the `call-with-current-continuation'
     function of the R5RS, see *note r5rs.info:
     (R5RS)call-with-current-continuation, but it is necessary to
     compile the module with the `-call/cc' option to use it, see
     Section *Note The Bigloo command line: Compiler Description.

     Note: Since `call/cc' is difficult to compile efficiently, one
     might consider using `bind-exit' instead.  For this reason, we
     decided to enable `call/cc' only with a compiler option.

 -- bigloo syntax: bind-exit escape body
     This form provides an escape operator facility. `bind-exit'
     evaluates the BODY, which may refer to the variable ESCAPE which
     will denote an "escape function" of one argument: when called,
     this escape function will return from the `bind-exit' form with
     the given argument as the value of the `bind-exit' form. The
     ESCAPE can only be used while in the dynamic extent of the form.
     Bindings introduced by `bind-exit' are immutable.

          (bind-exit (exit)
           (for-each (lambda (x)
                       (if (negative? x)
                           (exit x)))
                     '(54 0 37 -3 245 19))
           #t)                                  => -3

          (define list-length
            (lambda (obj)
              (bind-exit (return)
               (letrec ((r (lambda (obj)
                              (cond ((null? obj) 0)
                                    ((pair? obj)
                                     (+ (r (cdr obj)) 1))
                                    (else (return #f))))))
                    (r obj)))))

          (list-length '(1 2 3 4))               => 4
          (list-length '(a b . c))               => #f

 -- bigloo syntax: unwind-protect expr protect
     This form provides protections. Expression EXPR is evaluated. If
     this evaluation requires the invocation of an escape procedure (a
     procedure bounded by the `bind-exit' special form), PROTECT is
     evaluated before the control jump to the exit procedure. If EXPR
     does not raise any exit procedure, `unwind-protect' has the same
     behaviour as the `begin' special form except that the value of the
     form is always the value of EXPR.

          (define (my-open f)
             (if (file-exists? f)
                 (let ((port (open-input-file f)))
                    (if (input-port? port)
                        (unwind-protect
                           (bar port)
                           (close-input-port port))))))

 -- procedure: dynamic-wind before thunk after
     Calls THUNK without arguments, returning the result(s) of this
     call.  BEFORE and AFTER are called, also without arguments, as
     required by the following rules (note that in the absence of calls
     to continuations captured using `call/cc' the three arguments are called
     once each, in order).  BEFORE is called whenever execution enters
     the dynamic extent of the call to THUNK and AFTER is called
     whenever it exits that dynamic extent.  The dynamic extent of a
     procedure call is the period between when the call is initiated
     and when it returns.  In Scheme, because of `call/cc', the dynamic
     extent of a call may not be a single, connected time period.  It
     is defined as follows:

        * The dynamic extent is entered when execution of the body of
          the called procedure begins.

        * The dynamic extent is also entered when execution is not
          within the dynamic extent and a continuation is invoked that
          was captured (using `call/cc') during the dynamic extent.

        * It is exited when the called procedure returns.

        * It is also exited when execution is within the dynamic extent
          and a continuation is invoked that was captured while not
          within the dynamic extent.


     If a second call to `dynamic-wind' occurs within the dynamic
     extent of the call to THUNK and then a continuation is invoked in
     such a way that the AFTERs from these two invocations of
     `dynamic-wind' are both to be called, then the AFTER associated
     with the second (inner) call to `dynamic-wind' is called first.

     If a second call to `dynamic-wind' occurs within the dynamic
     extent of the call to THUNK and then a continuation is invoked in
     such a way that the BEFOREs from these two invocations of
     `dynamic-wind' are both to be called, then the BEFORE associated
     with the first (outer) call to `dynamic-wind' is called first.

     If invoking a continuation requires calling the BEFORE from one
     call to `dynamic-wind' and the AFTER from another, then the AFTER
     is called first.

     The effect of using a captured continuation to enter or exit the
     dynamic extent of a call to BEFORE or AFTER is undefined.

          (let ((path '())
                (c #f))
            (let ((add (lambda (s)
                         (set! path (cons s path)))))
              (dynamic-wind
                (lambda () (add 'connect))
                (lambda ()
                  (add (call/cc
                         (lambda (c0)
                           (set! c c0)
                           'talk1))))
                (lambda () (add 'disconnect)))
              (if (< (length path) 4)
                  (c 'talk2)
                  (reverse path))))

             => (connect talk1 disconnect connect talk2 disconnect)


 -- bigloo procedure: unspecified
     Returns the _unspecified_ (noted as `#unspecified') object with no
     specific property.

 -- bigloo syntax: try exp handler
     This form is documented in Section *note Errors and Assertions::.

 -- procedure: values obj ...
     Delivers all of its arguments to its continuation.  Except for
     continuations created by the `call-with-values' procedure, all
     continuations take exactly one value.  Values might be defined as
     follows:

          (define (values . things)
            (call/cc
              (lambda (cont) (apply cont things))))


 -- procedure: call-with-values producer consumer
     Calls its PRODUCER argument with no values and a continuation
     that, when passed some values, calls the CONSUMER procedure with
     those values as arguments.  The continuation for the call to
     CONSUMER is the continuation of the call to call-with-values.

          (call-with-values (lambda () (values 4 5))
                            (lambda (a b) b))
              => 5
          (call-with-values * -)
              => -1


 -- bigloo syntax: multiple-value-bind (var ...) producer exp ...
 -- bigloo syntax: receive (var ...) producer exp ...
     Evaluates EXP ... in a environment where VAR ... are bound from
     the evaluation of PRODUCER. The result of PRODUCER must be a call
     to `values' where the number of argument is the number of bound
     variables.
          (define (bar a)
             (values (modulo a 5) (quotient a 5)))

          (define (foo a)
             (multiple-value-bind (x y)
                (bar a)
                (print x " " y)))

          (foo 354)
             -| 4 70


File: bigloo.info,  Node: Input and Output,  Next: Serialization,  Prev: Scheme Library,  Up: Standard Library

4.2 Input and output
====================

This section describes Scheme operation for reading and writing data.
The section *note Files:: describes functions for handling files.

* Menu:

* Library functions::
* Memory mapped area::
* Gzip::
* Tar::


File: bigloo.info,  Node: Library functions,  Next: Memory mapped area,  Up: Input and Output

4.2.1 Library functions
-----------------------

 -- library procedure: call-with-input-file string proc
 -- library procedure: call-with-output-file string proc
     These two procedures call PROC with one argument, a port obtained
     by opening STRING.  See *note r5rs.info: (R5RS)Ports, for more
     details.

          (call-with-input-file "/etc/passwd"
             (lambda (port)
                (let loop ((line (read-line port)))
                   (if (not (eof-object? line))
                       (begin
                          (print line)
                          (loop (read-line port)))))))

 -- procedure: input-port? obj
 -- procedure: input-string-port? obj
 -- procedure: output-port? obj
 -- procedure: output-string-port? obj
 -- procedure: port? obj

 -- bigloo procedure: input-port-name obj
 -- bigloo procedure: output-port-name obj
     Returns the file name for which OBJ has been opened.

 -- bigloo (>=2.8b) procedure: input-port-timeout-set! port time
 -- bigloo (>=2.8b) procedure: output-port-timeout-set! port time
     These two functions limit the time an read or write operation may
     last.  If the TIME limit (expressed in microseconds) exceeded, an
     exception of time `&io-timeout-error' is raised.

 -- bigloo procedure: output-port-close-hook port
 -- bigloo procedure: output-port-close-hook-set! port proc
     Returns (resp. sets) the _close hook_ of the output PORT. The
     close hook is a procedure of one argument, the closed port. The
     hook is invoked _after_ the PORT is closed.

 -- bigloo procedure: input-port-close-hook port
 -- bigloo procedure: input-port-close-hook-set! port proc
     Returns (resp. sets) the _close hook_ of the input PORT. The close
     hook is a procedure of one argument, the closed port.

     Example:
          (let ((p (open-input-string "/etc/passwd")))
            (input-port-close-hook-set! p (lambda () (display 'done)))
            ...
            (close-input-port p))

 -- bigloo procedure: input-port-reopen! obj
     Re-open the input port OBJ. That is, re-start reading from the
     first character of the input port.

 -- procedure: current-input-port
 -- procedure: current-output-port
 -- bigloo procedure: current-error-port

 -- optional procedure: with-input-from-file string thunk
 -- optional procedure: with-input-from-string string thunk
 -- optional procedure: with-input-from-procedure procedure thunk
 -- optional procedure: with-output-to-file string thunk
 -- bigloo procedure: with-error-to-file string thunk
 -- bigloo procedure: with-output-to-string thunk
 -- bigloo procedure: with-output-to-procedure procedure thunk
 -- bigloo procedure: with-error-to-string thunk
 -- bigloo procedure: with-error-to-procedure procedure thunk
     A port is opened from file STRING. This port is made the current
     input port (resp. the current output port or the current error
     port) and THUNK is called.  See *note r5rs.info: (R5RS)Ports, for
     more details.

          (with-input-from-file "/etc/passwd"
             (lambda ()
                (let loop ((line (read-line (current-input-port))))
                   (if (not (eof-object? line))
                       (begin
                          (print line)
                          (loop (read-line (current-input-port))))))))

 -- bigloo procedure: with-input-from-port port thunk
 -- bigloo procedure: with-output-to-port port thunk
 -- bigloo procedure: with-error-to-port port thunk
     `with-input-from-port', `with-output-to-port' and
     `with-error-to-port' all suppose PORT to be a legal port. They
     call THUNK making PORT the current input (resp. output or error)
     port. None of these functions close PORT on the continuation of
     THUNK.

          (with-output-to-port (current-error-port)
             (lambda () (display "hello")))

 -- procedure: open-input-file file-name
     If FILE-NAME is a regular file name, `open-input-file' behaves as
     the function defined in the Scheme report. If FILE-NAME starts with
     special prefixes it behaves differently. Here are the recognized
     prefixes:

        * `| ' (a string made of the characters `#\|' and `#\space')
          Instead of opening a regular file, Bigloo opens an input pipe.
          The same syntax is used for output file.

               (define pin (open-input-file "| cat /etc/passwd"))
               (define pout (open-output-file "| wc -l"))

               (display (read pin) pout)
               (close-input-port pin)
               (newline pout)
               (close-output-port pout)

        * `pipe:' Same as `| '.

        * `file:' Opens a regular file.

        * `gzip:' Opens a port on a gzipped filed. This is equivalent to
          `open-input-gzip-file'.  Example:

               (with-input-from-file "gzip:bigloo.tar.gz"
                  (lambda ()
                     (send-chars (current-input-port) (current-output-port))))

        * `string:' Opens a port on a string. This is equivalent to
          `open-input-string'.  Example:

               (with-input-from-file "string:foo bar Gee"
                  (lambda ()
                     (print (read))
                     (print (read))
                     (print (read))))
                  -| foo
                  -| bar
                  -| Gee

        * `http:server/path'

          Opens an _http_ connection on `server' and open an input file
          on file `path'.

        * `http:server:port-number/path'

          Opens an _http_ connection on `server', on port number `port'
          and open an input file on file `path'.

        * `ftp:server/path'

          Opens an _http_ connection on `server' and open an input file
          on file `path'.

        * `ressource:'

          Opens a JVM _ressource_ file. Opening a `ressource:' file in
          non JVM backend always return `#f'. On the JVM backend it
          returns a input port if the ressource exists. Otherwise, it
          returns `#f'.


 -- bigloo procedure: open-input-gzip-file file-name
 -- bigloo procedure: open-input-gzip-port input-port
     Open respectively a gzipped file for input and a port on a gzipped
     stream.  Note that closing a gzip port opened from a port PI does
     not close the PI port.

          (let ((p (open-input-gzip-file "bigloo.tar.gz")))
             (unwind-protect
                (read-line p1)
                (close-input-port p)))

          (let* ((p1 (open-input-file "bigloo.tar.gz"))
                 (p2 (open-input-gzip-port p1)))
             (unwind-protect
                (read-line p2)
                (close-input-port p2)
                (close-input-port p1)))

 -- bigloo procedure: open-input-string string [start 0]
     Returns an `input-port' able to deliver characters from STRING.

 -- bigloo procedure: open-input-c-string string
     Returns an `input-port' able to deliver characters from C STRING.
     The buffer used by the input port is the exact same string as the
     argument. That is, no buffer is allocated.

 -- bigloo procedure: open-input-procedure procedure
     Returns an `input-port' able to deliver characters from PROCEDURE.
     Each time a character has to be read, the PROCEDURE is called.
     This procedure may returns a string of characters, or the boolean
     `#f'. This last value stands for the end of file.

     Example:

          (let ((p (open-input-procedure (let ((s #t))
          				  (lambda ()
          				     (if s
          					 (begin
                                                      (set! s #f)
                                                      "foobar")
          					 s))))))
             (read))

 -- procedure: open-output-file file-name
     The same syntax as `open-input-file' for file names applies here.
     When a file name starts with `| ', Bigloo opens an output pipe
     instead of a regular file.

 -- bigloo procedure: append-output-file file-name
     If `file-name' exists, this function returns an `output-port' on
     it, without removing it. New output will be appended to FILE-NAME.
     If `file-name' does not exist, it is created.

 -- bigloo procedure: open-output-string
     This function returns an _output string port_. This object has
     almost the same purpose as `output-port'. It can be used with all
     the printer functions which accept `output-port'. An output on a
     _output string port_ memorizes all the characters written. An
     invocation of `flush-output-port' or `close-output-port' on an
     _output string port_ returns a new string which contains all the
     characters accumulated in the port.

 -- bigloo procedure: get-output-string output-port
     Given an output port created by `open-output-string', returns a
     string consisting of the characters that have been output to the
     port so far.

 -- bigloo procedure: open-output-procedure proc [flush]
     This function returns an _output procedure port_. This object has
     almost the same purpose as `output-port'. It can be used with all
     the printer functions which accept `output-port'. An output on a
     _output procedure port_ invokes the PROC procedure each time it is
     used for writing. That is, PROC is invoked with a string denoting
     the displayed characters. When the function `flush-output-port' is
     called on such a port, the function optional FLUSH procedure is
     invoked.

 -- procedure: close-input-port input-port
 -- procedure: close-output-port output-port
     According to R5RS, the value returned is unspecified. However, if
     _output-port_ was created using `open-output-string', the value
     returned is the string consisting of all characters sent to the
     port.

 -- bigloo procedure: input-port-name input-port
     Returns the name of the file used to open the INPUT-PORT.

 -- bigloo procedure: input-port-position port
 -- bigloo procedure: output-port-position port
     Returns the current position (a character number), in the PORT.

 -- bigloo procedure: set-input-port-position! port pos
 -- bigloo procedure: set-output-port-position! port pos
     These functions set the file position indicator for PORT. The new
     position, measured in bytes, is specified by POS. It is an error
     to seek a port that cannot be changed (for instance, a string or a
     console port). The result of these functions is unspecified. An
     error is raised if the position cannot be changed.

 -- bigloo procedure: input-port-reopen! input-port
     This function re-opens the input `input-port'. That is, it reset
     the position in the INPUT-PORT to the first character.

 -- procedure: read [input-port]
 -- bigloo procedure: read/case case [input-port]
 -- bigloo procedure: read-case-sensitive [input-port]
 -- bigloo procedure: read-case-insensitive [input-port]
     Read a lisp expression. The case sensitivity of `read' is
     unspecified.  If have to to enforce a special behavior regarding
     the case, use `read/case', `read-case-sensitive' or
     `read-case-insensitive'.  Let us consider the following source
     code: The value of the `read/case''s CASE argument may either be
     `upcase', `downcase' or `sensitive'. Using any other value is an
     error.

          (define (main argv)
             (let loop ((exp (read-case-sensitive)))
                (if (not (eof-object? exp))
                    (begin
                       (display "exp: ")
                       (write exp)
                       (display " [")
                       (display exp)
                       (display "]")
                       (print " eq?: " (eq? exp 'FOO) " " (eq? exp 'foo))
                       (loop (read-case-sensitive))))))

     Thus:
          > a.out
          foo
            -| exp: foo [foo] eq?: #f #t
          FOO
            -| exp: FOO [FOO] eq?: #t #f

 -- bigloo procedure: read/rp grammar port
 -- bigloo procedure: read/lalrp lalrg rg port [emptyp]
     These functions are fully explained in *note Regular Parsing::,
     and *note Lalr Parsing::.

 -- procedure: read-char [port]
 -- procedure: read-byte [port]
 -- procedure: peek-char [port]
 -- procedure: peek-byte [port]
 -- procedure: eof-object? obj

 -- procedure: char-ready? [port]
     As specified in the R5Rs, *note r5rs.info: (R5RS)Ports,
     `char-ready?' returns #t if a character is ready on the input PORT
     and returns #f otherwise.  If `char-ready' returns #t then the
     next `read-char' operation on the given PORT is guaranteed not to
     hang.  If the PORT is at end of file then `char-ready?' returns
     #t.  PORT may be omitted, in which case it defaults to the value
     returned by `current-input-port'.

     When using `char-ready?' consider the latency that may exists
     before characters are available. For instance, executing the
     following source code:

          (let* ((proc (run-process "/bin/ls" "-l" "/bin" output: pipe:))
                 (port (process-output-port proc)))
             (let loop ((line (read-line port)))
                (print "char ready " (char-ready? port))
                (if (eof-object? line)
                    (close-input-port port)
                    (begin
                       (print line)
                       (loop (read-line port))))))

     Produces outputs such as:

          char ready #f
          total 7168
          char ready #f
          -rwxr-xr-x    1 root     root         2896 Sep  6  2001 arch
          char ready #f
          -rwxr-xr-x    1 root     root        66428 Aug 25  2001 ash
          char ready #t
          ...

     For a discussion of Bigloo processes, see *note Process::.

     _Note:_ Thanks to Todd Dukes for the example and the suggestion of
     including it this documentation.

 -- bigloo procedure: read-line [input-port]
     Reads characters from INPUT-PORT until a `#\Newline', a `#\Return'
     or an `end of file' condition is encountered.  `read-line' returns
     a newly allocated string composed of the characters read.

 -- bigloo procedure: read-lines [input-port]
     Accumulates all the line of an INPUT-PORT into a list.

 -- bigloo procedure: read-of-strings [input-port]
     Reads a sequence of non-space characters on INPUT-PORT, makes a
     string of them and returns the string.

 -- bigloo procedure: read-string [input-port]
     Reads all the characters of INPUT-PORT into a string.

 -- bigloo procedure: read-chars size [input-port]
 -- bigloo procedure: read-chars! buf size [input-port]
     The function `read-chars' returns a newly allocated strings made
     of SIZE characters read from INPUT-PORT (or from
     `(current-input-port)' if INPUT-PORT is not provided). If less
     than SIZE characters are available on the input port, the returned
     string is smaller than SIZE. Its size is the number of available
     characters.

     The function `read-char!' fills the buffer BUF with at most SIZE
     characters.

 -- bigloo procedure: port->string-list input-port
     Returns a list of strings composed of the elements of INPUT-PORT.

 -- bigloo procedure: port->list input-port reader
 -- bigloo procedure: port->sexp-list input-port
     `Port->list' applies reader to port repeatedly until it returns
     EOF, then returns a list of results.  `Port->list-sexp' is
     equivalent to `(port->list read port)'.

 -- bigloo procedure: send-chars input-port output-port [len] [offset]
     Transfer the characters from INPUT-PORT to OUTPUT-PORT. This
     procedure is sometimes mapped to a system call (such as `sendfile'
     under Linux) and might thus be more efficient than copying the
     ports by hand. The optional argument OFFSET specifies an offset
     from which characters of INPUT-PORT are sent. The function
     `send-chars' returns the number of characters sent.

 -- bigloo procedure: read-fill-string! s o len [input-port]
     Fills the string S starting at offset O with at most LEN
     characters read from the input port INPUT-PORT (or from
     `(current-input-port)' if INPUT-PORT is not provided).  This
     function returns the number of fill characters (which may be
     smaller than LEN if less characters are available).

     Example:
          (let ((s (make-string 10 #\-)))
             (with-input-from-string "abcdefghijlkmnops"
                (lambda ()
                   (read-fill-string! s 3 5)
                   s)))
             => ---abcde--

 -- library procedure: write obj [output-port]
 -- library procedure: display obj [output-port]
 -- bigloo procedure: print obj ...
     This procedure allows several objects to be displayed. When all
     these objects have been printed, `print' adds a newline.

 -- bigloo procedure: display* obj ...
     This function is similar to `print' but does not add a newline.

 -- bigloo procedure: fprint output-port obj ...
     This function is the same as `print' except that a port is
     provided.

 -- procedure: write-char char [output-port]
 -- procedure: write-byte byte [output-port]
     These procedures write a char (respec. a byte, i.e., in integer in
     the range 0..255) to the OUTPUT-PORT.

 -- procedure: newline [output-port]
 -- bigloo procedure: flush-output-port output-port
     This procedure flushes the output port OUTPUT-PORT.

 -- bigloo procedure: format format-string [objs]
     _Note_: Many thanks to Scott G. Miller who is the author of
     SRFI-28. Most of the documentation of this function is copied from
     the SRFI documentation.

     Accepts a message template (a Scheme String), and processes it,
     replacing any escape sequences in order with one or more
     characters, the characters themselves dependent on the semantics
     of the escape sequence encountered.

     An escape sequence is a two character sequence in the string where
     the first character is a tilde `~'. Each escape code's meaning is
     as follows:

        * `~a' The corresponding value is inserted into the string as
          if printed with display.

        * `~s' The corresponding value is inserted into the string as
          if printed with write.

        * `~%' A newline is inserted.

        * `~~' A tilde `~' is inserted.

     `~a' and `~s', when encountered, require a corresponding Scheme
     value to be present after the format string. The values provided
     as operands are used by the escape sequences in order. It is an
     error if fewer values are provided than escape sequences that
     require them.

     `~%' and `~~' require no corresponding value.

          (format "Hello, ~a" "World!")
             -| Hello, World!
          (format "Error, list is too short: ~s~%" '(one "two" 3))
             -| Error, list is too short: (one "two" 3)

 -- bigloo procedure: printf format-string [objs]
 -- bigloo procedure: fprintf port format-string [objs]
     Formats OBJS to the current output port or to the specified PORT.

 -- bigloo procedure: pp obj [output-port]
     Pretty print OBJ on OUTPUT-PORT.

 -- bigloo variable: *pp-case*
     Sets the variable to `respect', `lower' or `upper' to change the
     case for pretty-printing.

 -- bigloo variable: *pp-width*
     The width of the pretty-print.

 -- bigloo procedure: write-circle obj [output-port]
     Display recursive object OBJ on OUTPUT-PORT. Each component of the
     object is displayed using the `write' library function.

 -- bigloo procedure: display-circle obj [output-port]
     Display recursive object OBJ on OUTPUT-PORT. Each component of the
     object is displayed using the `display' library function.

     For instance:
          (define l (list 1 2 3))
          (set-car! (cdr l) l)
          (set-car! (cddr l) l)
          (display-circle l)  -| #0=(1 #0# #0#)

 -- bigloo procedure: display-string string output-port
 -- bigloo procedure: display-substring string start end output-port
     STRING must be a string, and START and END must be exact integers
     satisfying   `0 <= start <= end <= (string-length string)'.

     `Display-substring' displays a string formed from the characters
     of string beginning with index START (inclusive) and ending with
     index END (exclusive).

 -- bigloo procedure: password [prompt]
     Reads a password from the current input port. The reading stops
     when the user hits the ,(code "Enter") key.


File: bigloo.info,  Node: Memory mapped area,  Next: Gzip,  Prev: Library functions,  Up: Input and Output

4.2.2 mmap
----------

The `mmap' function asks to map a file into memory. This memory area
can be randomly accessed as a string. In general using `mmap' improves
performance in comparison with equivalent code using regular ports.

 -- bigloo procedure: mmap? obj
     Returns `#t' if and only if OBJ has been produced by `open-mmap'.
     Otherwise, it returns `#f'.

 -- bigloo procedure: open-mmap path [mode]
     Maps a file PATH into memory. The optional argument MODE specifies
     how the file is open. The argument can be:

        * `read: #t' The memory can be read

        * `read: #f' The memory cannot be read

        * `write: #t' The memory can be written

        * `write: #f' The memory is read-only.

 -- bigloo procedure: close-mmap mm
     Closes the memory mapped. Returns `#t' on success, `#f' otherwise.

 -- bigloo procedure: mmap-length mm
     Returns the length, an exact integer, of the memory mapped.

 -- bigloo procedure: mmap-read-position mm
 -- bigloo procedure: mmap-read-position-set! mm offset
 -- bigloo procedure: mmap-write-position mm
 -- bigloo procedure: mmap-write-position-set! mm offset
     Returns and sets the read and write position of a memory mapped
     memory.  The result and the argument are exact integers.

 -- bigloo procedure: mmap-ref mm offset
     Reads the character in MM at OFFSET, an exact long (::elong). This
     function sets the read position to `offset + 1'.

 -- bigloo procedure: mmap-set! mm offset char
     Writes the character CHAR in MM at OFFSET, an exact long
     (::elong). This function sets the write position to `offset + 1'.

 -- bigloo procedure: mmap-substring mm start end
     Returns a newly allocated string made of the characters read from
     MM starting at position START and ending at position END - 1.  If
     the values `start' and `end' are not ranged in `[0...(mmap-length
     mm)]', an error is signaled. The function `mmap-substring' sets
     the read position to `end'.

 -- bigloo procedure: mmap-substring-set! mm start str
     Writes the string STR to MM at position START.  If the values
     `start' and `start + (string-length str)' are not ranged in
     `[0...(mmap-length mm)[', an error is signaled. The function
     `mmap-substring' sets the write position to `start +
     (string-length str)'.

 -- bigloo procedure: mmap-get-char mm
 -- bigloo procedure: mmap-put-char! mm c
 -- bigloo procedure: mmap-get-string mm len
 -- bigloo procedure: mmap-put-string! mm str
     These functions get (resp. put) character and strings into a
     memory mapped area. They increment the read (resp. write)
     position. An error is signaled if the characters read (resp.
     writen) outbound the length of the memory mapped.


File: bigloo.info,  Node: Gzip,  Next: Tar,  Prev: Memory mapped area,  Up: Input and Output

4.2.3 Gzip
----------

 -- bigloo procedure: port->gzip-port input-port bufsiz
     This function takes a regular port as input (INPUT-PORT). It
     constructs a new ports that automatically _unzip_ the read
     characters.

 -- bigloo procedure: open-input-gzip-file path [bufsiz]
     This function opens a gzipped file for input. The file is
     automatically unzipped when the characters are read. It is
     equivalent to:

          (let ((p (open-input-port path)))
            (port->gzip-port p))

     Gzipped files can also be using the `gzip:' prefix. That is:

          (open-input-gzip-file "a-path.gz")

     is equivalent to:

          (open-input-file "gzip:a-path.gz")

 -- bigloo procedure: gunzip-sendchars input-port output-port
     Transmit all the characters from the gzipped INPUT-PORT to the
     OUTPUT-PORT.

     Note that the function `send-chars' can also be used on gzipped
     input-ports.

 -- bigloo procedure: gunzip-parse-header input-port
     Parse the header of INPUT-PORT. Returns `#f' if and only if the
     port is not gzipped.


File: bigloo.info,  Node: Tar,  Prev: Gzip,  Up: Input and Output

4.2.4 Tar
---------

 -- bigloo procedure: tar-read-header [input-port]
     Reads a tar header from INPUT-PORT. If the input-port does not
     conform the tar format, an IO exception is raised. On success a
     _tar-header_ descriptor is returned.

 -- bigloo procedure: tar-read-block tar-header [input-port]
     Reads the content of the TAR-HEADER block.

 -- bigloo procedure: tar-round-up-to-record-size int
     Rounds up tar-block sizes.

 -- bigloo procedure: tar-header-name tar-header
 -- bigloo procedure: tar-header-mode tar-header
 -- bigloo procedure: tar-header-uid tar-header
 -- bigloo procedure: tar-header-gid tar-header
 -- bigloo procedure: tar-header-size tar-header
 -- bigloo procedure: tar-header-mtim tar-header
 -- bigloo procedure: tar-header-checksum tar-header
 -- bigloo procedure: tar-header-type tar-header
 -- bigloo procedure: tar-header-linkname tar-header
 -- bigloo procedure: tar-header-uname tar-header
 -- bigloo procedure: tar-header-gname tar-header
 -- bigloo procedure: tar-header-devmajor tar-header
 -- bigloo procedure: tar-header-devminir tar-header
     Return various information about TAR-HEADER.

  The following example simulates the Unix command `tar xvfz':

     (define (untar path)
        (let ((pz (open-input-gzip-port path)))
           (unwind-protect
     	 (let loop ((lst '()))
     	    (let ((h (tar-read-header pz)))
     	       (if (not h)
     		   lst
     		   (case (tar-header-type h)
     		      ((dir)
     		       (let ((path (tar-header-name h)))
     			  (if (make-directory path)
     			      (loop lst)
     			      (error 'untar
     				     "Cannot create directory"
     				     path))))
     		      ((normal)
     		       (let* ((path (tar-header-name h))
     			      (dir (dirname path)))
     			  (when (and (file-exists? dir) (not (directory? dir)))
     			     (delete-file dir))
     			  (unless (file-exists? dir)
     			     (make-directory dir))
     			  (with-output-to-file path
     			     (lambda ()
     				(display (tar-read-block h pz))))
     			  (loop (cons path lst))))
     		      (else
     		       (error 'untar
     			      (format "Illegal file type `~a'"
     				      (tar-header-type h))
     			      (tar-header-name h)))))))
     	 (close-input-port pz))))

 -- bigloo procedure: untar input-port [:directory (pwd)] [:file #f]
     Untars the archive whose content is provided by the input port
     INPUT-PORT.

        * If :FILE is provided, `untar' extract the content of the file
          named :FILE and returns a string. The file name must exactly
          matches the files of the archive files names. If the file
          does not exist, `untar' returns `#f'.

        * If :FILE is not provided, it _untars_ the whole content, in
          the directory denoted by :DIRECTORY, which defaults to
          `(pwd)'.  The function `untar', returns the whole list of
          created directories and files.



File: bigloo.info,  Node: Serialization,  Next: Bit Manipulation,  Prev: Input and Output,  Up: Standard Library

4.3 Serialization
=================

 -- bigloo procedure: string->obj string
     This function converts a STRING which has been produced by
     `obj->string' into a Bigloo object.

 -- bigloo procedure: obj->string object
     This function converts into a string _any_ Bigloo OBJECT which
     does not contain a procedure.

  The implementation of the last two functions ensures that for every
Bigloo  object `obj' (containing no procedure), the expression:

     (equal? obj (string->obj (obj->string obj)))
        => #t

 -- bigloo procedure: binary-port? obj
 -- bigloo procedure: open-output-binary-file file-name
 -- bigloo procedure: append-output-binary-file file-name
 -- bigloo procedure: open-input-binary-file file-name
 -- bigloo procedure: close-binary-port binary-port
 -- bigloo procedure: flush-binary-port binary-port
 -- bigloo procedure: input-obj binary-port
 -- bigloo procedure: output-obj binary-port obj
     Bigloo allows Scheme objects to be dumped into, and restored from,
     files.  These operations are performed by the previous functions.
     The dump and the restore use the two functions `obj->string' and
     `string->obj'.

     It is also possible to use a binary file as a flat character file.
     This can be done by the means of `output-char', `input-char',
     `output-string', and `input-string' functions.

 -- bigloo procedure: input-char binary-port
 -- bigloo procedure: output-char binary-port
     The function `input-char' reads a single character from a
     BINARY-PORT. It returns the read character or the `end-of-file'
     object. The function `output-char' writes a character into a
     BINARY-PORT.

 -- bigloo procedure: input-string binary-port len
 -- bigloo procedure: output-string binary-port
     The function `input-string' reads a string from a BINARY-PORT of
     maximum length LEN. It returns a newly allocated string whose
     length is possibly smaller than LEN. The function `output-string'
     writes a string into a BINARY-PORT.

 -- bigloo procedure: input-fill-string! binary-port string
     Fills a string with characters read from BINARY-PORT with at most
     the length of STRING. The function returns the number of filled
     characters.

 -- bigloo procedure: register-procedure-serialization! serializer
          unserializer
 -- bigloo procedure: register-custom-serialization! ident serializer
          unserializer
 -- bigloo procedure: register-process-serialization! serializer
          unserializer
 -- bigloo procedure: register-opaque-serialization! serializer
          unserializer
     There is no existing portable method to dump and restore a
     procedure. Thus, if `obj->string' is passed a procedure, it will
     emit an error message.  Sometime, using strict restrictions, it
     may be convenient to use an ad-hoc framework to serialize and
     unserialize procedures. User may specify there own procedure
     serializer and unserializer. This is the role of
     `register-procedure-serialization!'. The argument SERIALIZER is a
     procedure of one argument, converting a procedure into a
     characters strings. The argument UNSERIALIZER is a procedure of
     one argument, converting a characters string into a procedure. It
     belongs to the user to provide correct serializer and unserializer.

     Here is an example of procedure serializer and unserializer that
     may be correct under some Unix platform:

          (module foo
             (extern (macro %sprintf::int (::string ::string ::procedure) "sprintf")))

          (define (string->procedure str)
             (pragma "(obj_t)(strtoul(BSTRING_TO_STRING($1), 0, 16))" str))

          (define (procedure->string proc)
             (let ((item (make-string 10)))
                (%sprintf item "#p%lx" proc)
                item))

          (register-procedure-serialization! procedure->string string->procedure)

          (let ((x 4))
             (let ((obj (cons "toto" (lambda (y) (+ x y)))))
                (let ((nobj (string->obj (obj->string obj))))
          	 (print ((cdr nobj) 5)))))

 -- bigloo procedure: register-class-serialization! class serializer
          unserializer
     Register a serializer/unserializer for a class. Subclasses of CLASS
     inherit this serializer.

          (module class-serialization-example
             (static (class point::object (x (default 10)) (y (default 20)))))

          (register-class-serialization! point
          			       (lambda (o)
          				  (with-access::point o (x y)
          				     (cons x y)))
          			       (lambda (l)
          				  (instantiate::point
          				     (x (car l))
          				     (y (cdr l)))))

          (let ((o (instantiate::point)))
             (let ((s (obj->string (list o o))))
                (print (string-for-read s))
                (let ((l (string->obj s)))
          	 (print l)
          	 (eq? (car l) (cadr l))))) => #t

 -- bigloo procedure: get-procedure-serialization
 -- bigloo procedure: get-custom-serialization ident
 -- bigloo procedure: get-process-serialization
 -- bigloo procedure: get-opaque-serialization
 -- bigloo procedure: get-class-serialization class
     Returns the a multiple-values whose first element is the current
     procedure serializer and whose second element is the current
     procedure unserializer.  If no serializer/unserializer is defined,
     these procedures return the values `#f #f'.


File: bigloo.info,  Node: Bit Manipulation,  Next: Weak Pointers,  Prev: Serialization,  Up: Standard Library

4.4 Bit manipulation
====================

These procedures allow the manipulation of fixnums as bit-fields.

 -- bigloo procedure: bit-or i1 i2
 -- bigloo procedure: bit-orelong i1 i2
 -- bigloo procedure: bit-orllong i1 i2
 -- bigloo procedure: bit-xor i1 i2
 -- bigloo procedure: bit-xorelong i1 i2
 -- bigloo procedure: bit-xorllong i1 i2
 -- bigloo procedure: bit-and i1 i2
 -- bigloo procedure: bit-andelong i1 i2
 -- bigloo procedure: bit-andllong i1 i2
 -- bigloo procedure: bit-not i
 -- bigloo procedure: bit-notelong i
 -- bigloo procedure: bit-notllong i
 -- bigloo procedure: bit-lsh i1 i2
 -- bigloo procedure: bit-lshelong i1 i2
 -- bigloo procedure: bit-lshllong i1 i2
 -- bigloo procedure: bit-rsh i1 i2
 -- bigloo procedure: bit-ursh i1 i2
 -- bigloo procedure: bit-rshelong i1 i2
 -- bigloo procedure: bit-rshllong i1 i2
          (bit-or 5 3)                           => 7
          (bit-orelong #e5 #e3)                  => #e7
          (bit-xor 5 3)                          => 6
          (bit-andllong #l5 #l3)                 => #l1
          (bit-not 5)                            => -6
          (bit-lsh 5 3)                          => 40
          (bit-rsh 5 1)                          => 2


File: bigloo.info,  Node: Weak Pointers,  Next: Hash Tables,  Prev: Bit Manipulation,  Up: Standard Library

4.5 Weak Pointers
=================

Bigloo may support weak pointers. In order to activate this support,
Bigloo must be configured with the `finalization' enabled.  That is,
the `configure' script must be invoked with the option
`--finalization=yes'. When the finalization and weak pointers support
is enabled, Bigloo defines the `cond-expand' properties
`bigloo-finalizer' and `bigloo-weakptr'.  Then a program may test the
support with expressions such as:

     (cond-expand
       (bigloo-weakptr <something>)
       (else <something-else>))

  Weak pointers are pointers to objects which can be collected by the
garbage collector if they are weakly pointed to. An object is weakly
pointed to if the only pointers to it are weak pointers. Weakly pointed
objects can be collected by the garbage collector, and all the weak
pointers to such objects will cease to point to it and point to
`#unspecified' instead.

 -- bigloo procedure: make-weakptr data
     Creates a weak pointer to DATA.

 -- bigloo procedure: weakptr? obj
     Returns `#t' if OBJ is a weak pointer, constructed by
     `make-weakptr'.

 -- bigloo procedure: weakptr-data ptr
     Returns the data object pointed to by PTR. If the object has been
     collected, it returns `#unspecified'.


File: bigloo.info,  Node: Hash Tables,  Next: System Programming,  Prev: Weak Pointers,  Up: Standard Library

4.6 Hash Tables
===============

Bigloo offers hash tables with support for weak pointers. Here are
described functions which define and use them.

 -- bigloo procedure: make-hashtable [bucket-len] [max-bucket-len]
          [eq-test] [hashn] [weak-keys] [weak-data]
     Defines an hash table for which the number of buckets is
     BUCKET-LEN.  The variable MAX-BUCKET-LEN specify when the table
     should be resized. If provided, these two values have to be exact
     integers greater or equal to 1. Normally you could ignore
     BUCKET-LEN and MAX-BUCKET-LEN arguments and call `make-hashtable'
     with no argument at all. The argument EQTEST enables the
     specification of a comparison function. The first argument of this
     function is the keys contained in the table. The second argument
     is the searched key. By default hash tables rely on `equal?'. The
     argument HASHN specifies an hashing function. It defaults to
     GET-HASHNUMBER.  The arguments WEAK-KEYS and WEAK-DATA specify
     respectively whether the hash table should use weak pointers to
     store the keys and/or the data.  By default a hash table uses
     strong pointers for both keys and data.  Each optional arguments
     BUCKET-LEN, MAX-BUCKET-LEN, EQ-TEST, HASHN, WEAK-KEYS, and
     WEAK-DATA can be bound to the Bigloo value `#unspecified' which
     forces its default.

 -- bigloo procedure: hashtable? obj
     Returns `#t' if OBJ is an hash table, constructed by
     `make-hashtable'.

 -- bigloo procedure: hashtable-weak-keys? table
     Returns `#t' if TABLE is a hash table with weakly pointed keys.

 -- bigloo procedure: hashtable-weak-data? table
     Returns `#t' if TABLE is a hash table with weakly pointed data.

 -- bigloo procedure: hashtable-size table
     Returns the number of entries contained in TABLE.  Note that for a
     weak hash table the size does not guarantee the real size, since
     keys and/or data can dissapear before the next call to the hash
     table.

 -- bigloo procedure: hashtable-contains? table key
     Returns the boolean `#t' if it exists at least one entry whose key
     is KEY in TABLE. If not entry is found `#f' is returned.  Note
     that for a weak hash table, the fact this procedure returns `#t'
     does not guarantee that the key (or its associated data) will not
     dissapear before the next call to the hash table.

 -- bigloo procedure: hashtable-get table key
     Returns the entry whose key is KEY in TABLE. If no entry is found,
     or if the key and/or value is weakly pointed to and has dissapeard,
     `#f' is returned.

 -- bigloo procedure: hashtable-put! table key obj
     Puts OBJ in TABLE under the key KEY. This function returns the
     object bound in the table. If there was an object OBJ-OLD already
     in the table with the same key as OBJ, this function returns
     OBJ-OLD; otherwise it returns OBJ.

 -- bigloo procedure: hashtable-remove! table key
     Removes the object associated to KEY from TABLE, returning `#t' if
     such object was bound in table and `#f' otherwise.

 -- bigloo procedure: hashtable-update! table key update-fun init-value
     If key is already in table, the new value is calculated by
     `(update-fun current-value)'. Otherwise the TABLE is extended by
     an entry linking key and `init-value'.

 -- bigloo procedure: hashtable->vector table
 -- bigloo procedure: hashtable->list table
     Returns the hash table TABLE's data as a vector or a list.  If the
     hash table is weak, the result will consist only of the data which
     haven't dissapeared yet and whose keys haven't dissapeared either.

 -- bigloo procedure: hashtable-key-list table
     Returns the list of keys used in the TABLE.  If the hash table is
     weak, the result will consist only of the keys which haven't
     dissapeared yet and whose data haven't dissapeared either.

 -- bigloo procedure: hashtable-map table fun
     Returns a list whose elements are the result of applying FUN to
     each of the keys and elements of TABLE (no order is specified). In
     consequence, FUN must be a procedure of two arguments. The first
     one is a key and the second one, an associated object.  If the
     hash table is weak, FUN will only be mapped on sets of key/datum
     which haven't dissapeared yet.

 -- bigloo procedure: hashtable-for-each table fun
     Applies FUN to each of the keys and elements of TABLE (no order is
     specified). In consequence, FUN must be a procedure of two
     arguments. The first one is a key and the second one, an
     associated object.  If the hash table is weak, FUN will only be
     called on sets of key/datum which haven't dissapeared yet.

 -- bigloo procedure: hashtable-filter! table fun
     Filter out elements from TABLE according to predicate FUN.  If the
     hash table is weak, FUN will only be called on sets of key/datum
     which haven't dissapeared yet.

  Here is an example of hash table.

     (define *table* (make-hashtable))

     (hashtable-put! *table* "toto" "tutu")
     (hashtable-put! *table* "tata" "titi")
     (hashtable-put! *table* "titi" 5)
     (hashtable-put! *table* "tutu" 'tutu)
     (hashtable-put! *table* 'foo 'foo)

     (print (hashtable-get *table* "toto"))
        -| "tutu"
     (print (hashtable-get *table* 'foo))
        -| 'foo
     (print (hashtable-get *table* 'bar))
        -| #f

     (hashtable-for-each *table* (lambda (key obj) (print (cons key obj))))
        -| ("toto" . "tutu")
           ("tata" . "titi")
           ("titi" . 5)
           ("tutu" . TUTU)
           (foo . foo)

 -- bigloo generic: object-hashnumber object
     This generic function computes a hash number of the instance
     OBJECT.

     Example:
          (define-method (object-hashnumber pt::point)
             (with-access::point pt (x y)
                (+fx (*fx x 10) y)))


File: bigloo.info,  Node: System Programming,  Next: Date,  Prev: Hash Tables,  Up: Standard Library

4.7 System programming
======================

* Menu:

* Operating System Interface::
* Files::
* Process::
* Socket::
* SSL::


File: bigloo.info,  Node: Operating System Interface,  Next: Files,  Up: System Programming

4.7.1 Operating System interface
--------------------------------

 -- bigloo procedure: register-exit-function! proc
     Register PROC as an exit functions. PROC is a procedure accepting
     of one argument. This argument is the numerical value which is the
     status of the exit call. The registered functions are called when
     the execution ends.

 -- bigloo procedure: exit int
     Apply all the registered exit functions then stops an execution,
     returning the integer INT.

 -- bigloo procedure: signal n proc
     Provides a signal handler for the operating system dependent signal
     N. PROC is a procedure of one argument.

 -- bigloo procedure: get-signal-handler n
     Returns the current handler associated with signal N or `#f' if no
     handler is installed.

 -- bigloo procedure: system . strings
     Append all the arguments STRINGS and invoke the native host
     `system' command on that new string which returns an integer.

 -- bigloo procedure: system->string . strings
     Append all the arguments STRINGS and invoke the native host
     `system' command on that new string. If the command completes,
     `system->string' returns a string made of the output of the
     command.

 -- bigloo procedure: getenv string
     Returns the string value of the Unix shell's STRING variable. If no
     such variable is bound, `getenv' returns `#f'.

 -- bigloo procedure: putenv string val
     Adds or modifies the global environment variable STRING so that it
     is bound to VAL after the call. This facility is not supported by
     all back-end. In particular, the JVM back-end does not support it.

 -- bigloo procedure: date
     Returns the current date in a `string'. See also *note Date::.

 -- bigloo procedure: sleep micros
     Sleeps for a delay during at least MICROS microseconds.

 -- bigloo procedure: command-line
     Returns a list of strings which are the Unix command line
     arguments.

 -- bigloo procedure: executable-name
     Returns the name of the running executable.

 -- bigloo procedure: os-class
     Gives the OS class (e.g. `unix').

 -- bigloo procedure: os-name
     Gives the OS name (e.g. `Linux').

 -- bigloo procedure: os-arch
     Gives the host architecture (e.g. `i386').

 -- bigloo procedure: os-version
     Gives the operating system version (e.g. `RedHat 2.0.27').

 -- bigloo procedure: os-tmp
     Gives the regular temporary directory (e.g. `/tmp').

 -- bigloo procedure: file-separator
     Gives the operating system file separator (e.g. `#\/').

 -- bigloo procedure: path-separator
     Gives the operating system file path separator (e.g.`#\:').

  For additional functions (such as `directory->list') see *note Input
and Output::.

 -- bigloo procedure: unix-path->list
     Converts a Unix path to a Bigloo list of strings.

          (unix-path->list ".")           => (".")
          (unix-path->list ".:/usr/bin")  => ("." "/usr/bin")


 -- bigloo procedure: hostname
     Returns the fully qualified name of the current host.

 -- bigloo procedure: time thunk
     Evaluates the THUNK and returns four values: the result of calling
     THUNK, the actual execution time, the system time, and the user
     time.

          (multiple-value-bind (res rtime stime utime)
            (time (lambda () (fib 35)))
            (print "real: " rtime " sys: " stime " user: " stime))



File: bigloo.info,  Node: Files,  Next: Process,  Prev: Operating System Interface,  Up: System Programming

4.7.2 Files
-----------

See *note Input and Output:: for file and directory handling. This
section only deals with _name_ handling. Four procedures exist to
manipulate Unix filenames.

 -- bigloo procedure: basename string
     Returns a copy of STRING where the longest prefix ending in `/' is
     deleted if any existed.

 -- bigloo procedure: prefix string
     Returns a copy of STRING where the suffix starting by the char
     `#\.' is deleted. If no prefix is found, the result of `prefix' is
     a copy of `string'. For instance:

          (prefix "foo.scm")
             => "foo"
          (prefix "./foo.scm")
             => "./foo"
          (prefix "foo.tar.gz")
             => "foo.tar"

 -- bigloo procedure: suffix string
     Returns a new string which is the suffix of STRING. If no suffix
     is found, this function returns an empty string. For instance,

          (suffix "foo.scm")
             => "scm"
          (suffix "./foo.scm")
             => "scm"
          (suffix "foo.tar.gz")
             => "gz"

 -- bigloo procedure: dirname string
     Returns a new string which is the directory component of STRING.
     For instance:

          (dirname "abc/def/ghi")
             => "abc/def"
          (dirname "abc")
             =>  "."
          (dirname "abc/")
             => "abc"
          (dirname "/abc")
             => "/"

 -- bigloo procedure: pwd
     Returns the current working directory.

 -- bigloo procedure: chdir dir-name
     Changes the current directory to DIR-NAME. On success, `chdir'
     returns `#t'. On failure it returns `#f'.

 -- bigloo procedure: make-file-name dir-name name
     Make an absolute file-name from a directory name DIR-NAME and a
     relative name NAME.

 -- bigloo procedure: make-file-path dir-name name . names
     Make an absolute file-name from a directory name DIR-NAME and a
     relative name NAMEs.

 -- bigloo procedure: file-name->list name
     Explodes a file name into a list.

          (file-name->list "/etc/passwd")
             => '("" "etc" "passwd")
          (file-name->list "etc/passwd")
             => '("etc" "passwd")

 -- bigloo procedure: file-name-canonicalize name
 -- bigloo procedure: file-name-canonicalize! name
 -- bigloo procedure: file-name-unix-canonicalize name
 -- bigloo procedure: file-name-unix-canonicalize! name
     Canonicalizes a file name. If the file name is malformed this
     function raises an `&io-malformed-url-error' exception.

     In addition to handling `..' directory name, the function
     `file-name-unix-canonicalize' also handles the `~' character.

          (file-name-canonicalize "/etc/passwd")
             => "/etc/passwd"
          (file-name-canonicalize "/etc/../tmp/passwd")
             => "/tmp/passwd"
          (file-name-canonicalize "~/passwd")
             => "~/passwd"
          (file-name-unix-canonicalize "~/passwd")
             => "/home/a-user/passwd"
          (file-name-unix-canonicalize "~foo/passwd")
             => "/home/foo/passwd"

 -- bigloo procedure: relative-file-name name base
     Builds a file name relative to BASE.

          (find-file/path "/etc/passwd" "/etc"
             => "passwd"

 -- bigloo procedure: find-file/path name path
     Search, in sequence, in the directory list PATH for the file NAME.
     If NAME is an absolute name, then PATH is not used to find the
     file. If NAME is a relative name, the function `make-file-name' is
     used to build absolute name from NAME and the directories in PATH.
     The current path is not included automatically in the list of
     PATH. In consequence, to check the current directory one may add
     `"."' to the PATH list. On success, the absolute file name is
     returned. On failure, `#f' is returned. Example:

          (find-file/path "/etc/passwd" '("/toto" "/titi"))
             => "/etc/passwd"
          (find-file/path "passwd" '("/toto" "/etc"))
             => "/etc/passwd"
          (find-file/path "pass-wd" '("." "/etc"))
             => #f

 -- bigloo procedure: make-static-library-name name
     Make a static library name from NAME by adding the static library
     regular suffix.

 -- bigloo procedure: make-shared-library-name name
     Make a shared library name from NAME by adding the shared library
     regular suffix.

 -- bigloo procedure: file-exists? string
     This procedure returns `#t' if the file STRING exists. Otherwise
     it returns `#f'.

 -- bigloo procedure: file-gzip? string
     This procedure returns `#t' if and only if the file STRING exists
     and can be unzip by Bigloo. Otherwise it returns `#f'.

 -- bigloo procedure: delete-file string
     Deletes the file named STRING. The result of this procedure is
     `#t' is the operation succeeded. The result is `#f' otherwise.

 -- bigloo procedure: rename-file string1 string2
     Renames the file STRING1 as STRING2. The two files have to be
     located on the same file system. If the renaming succeeds, the
     result is `#t', otherwise it is `#f'.

 -- bigloo procedure: copy-file string1 string2
     Copies the file STRING1 into STRING2. If the copy succeeds, the
     result is `#t', otherwise it is `#f'.

 -- bigloo procedure: directory? string
     This procedure returns `#t' if the file STRING exists and is a
     directory. Otherwise it returns `#f'.

 -- bigloo procedure: make-directory string
     Creates a new directory named STRING. It returns `#t' if the
     directory was created. It returns `#f' otherwise.

 -- bigloo procedure: make-directories string
     Creates a new directory named STRING, including any necessary but
     nonexistent parent directories. It returns `#t' if the directory
     was created. It returns `#f' otherwise. Note that if this
     operation fails it may have succeeded in creating some of the
     necessary parent directories.

 -- bigloo procedure: delete-directory string
     Deletes the directory named STRING. The directory must be empty in
     order to be deleted. The result of this procedure is unspecified.

 -- bigloo procedure: directory->list string
 -- bigloo procedure: directory->path-list string
     If file STRING exists and is a directory, the function
     `directory->list' returns the list of files in STRING.  The
     function `directory->path-list' returns a list of files whose
     dirname is STRING.

 -- bigloo procedure: file-modification-time string
     The date (in second) of the last modification for file STRING. The
     number of seconds is represented by a value that may be converted
     into a date by the means of `seconds->date' (see *note Date::).

 -- bigloo procedure: file-size string
     Returns the size (in bytes) for file STRING. The return type is
     `long'. If an full-sized integer is needed, one may write:

          (let ((sz::llong (file-size <PATH>)))
           ...)

          On error, `-1' is returned.


 -- bigloo procedure: file-uid string
 -- bigloo procedure: file-gid string
     The functions return the user id (an integer) and group id (an
     integer) for file STRING. On error, `-1' is returned.

 -- bigloo procedure: file-mode string
     Returns the file access mode (an integer). On error `-1' is
     returned.

 -- bigloo procedure: chmod string [option]
     Change the access mode of the file named STRING. The OPTION must
     be either a list of the following symbols `read', `write' and
     `execute' or an integer. If the operation succeeds, `chmod'
     returns `#t'. It returns `#f' otherwise. The argument OPTION can
     also be an integer that represents the native file permission.
     Example:

          (chmod (make-file-name (getenv "HOME") ".bigloorc") 'read 'write)
          (chmod (make-file-name (getenv "HOME") ".bigloorc") #o777)


File: bigloo.info,  Node: Process,  Next: Socket,  Prev: Files,  Up: System Programming

4.7.3 Process support
---------------------

Bigloo provides access to Unix-like processes as first class objects.
The implementation and this documentation are to a great extent copies
of the STk [Gallesio95] process support. Basically, a process contains
four informations: the standard Unix process identification (aka PID)
and the three standard files of the process.

 -- bigloo procedure: run-process command arg...
     `run-process' creates a new process and run the executable
     specified in COMMAND. The ARG correspond to the command line
     arguments.  When is process completes its execution, non pipe
     associated ports are automatically closed. Pipe associated ports
     have to be explicitly closed by the program. The following values
     of P have a special meaning:

        * `input:' permits to redirect the standard input file of the
          process.  Redirection can come from a file or from a pipe. To
          redirect the standard input from a file, the name of this
          file must be specified after `input:'.  Use the special
          keyword `pipe:' to redirect the standard input from a pipe.

        * `output:' permits to redirect the standard output file of the
          process.  Redirection can go to a file or to a pipe. To
          redirect the standard output to a file, the name of this file
          must be specified after `output:'. Use the special keyword
          `pipe:' to redirect the standard output to a pipe.

        * `error:' permits to redirect the standard error file of the
          process.  Redirection can go to a file or to a pipe. To
          redirect the standard error to a file, the name of this file
          must be specified after `error:'. Use the special keyword
          `pipe:' to redirect the standard error to a pipe.

        * `wait:' must be followed by a boolean value. This value
          specifies if the process must be ran asynchronously or not. By
          default, the process is run asynchronously (i.e. `wait:' if
          `#f').

        * `host:' must be followed by a string. This string represents
          the name of the machine on which the COMMAND must be
          executed. This option uses the external command `rsh'. The
          shell variable `PATH' must be correctly set for accessing it
          without specifying its absolute path.

        * `fork:' must be followed by a boolean value. This value
          specifies if the process must substitute the current
          execution. That is, if the value is `#t' a new process is
          spawned otherwise, the current execution is stopped and
          replaced by the execution of `command'. It defaults to `#t'.

        * `env:' must be followed by a string of the form `VAR=VAL'.
          This will bound an environment variable in the spawned
          process. A `run-process' command may contain several `env:'
          arguments. The current variables of the current process are
          also passed to the new process.

     The following example launches a process which execute the Unix
     command `ls' with the arguments `-l' and `/bin'. The lines printed
     by this command are stored in the file `tmp/X'.

          (run-process "ls" "-l" "/bin" output: "/tmp/X")

     The same example with a pipe for output:

          (let* ((proc (run-process "ls" "-l" "/bin" output: pipe:))
                 (port (process-output-port proc)))
             (let loop ((line (read-line port)))
                (if (eof-object? line)
                    (close-input-port port)
                    (begin
                       (print line)
                       (loop (read-line port))))))

     One should note that the same program can be written with explicit
     process handling but making use of the `|' notation for
     `open-input-file'.

          (let ((port (open-input-file "| ls -l /bin")))
             (let loop ((line (read-line port)))
                (if (eof-object? line)
                    (close-input-port port)
                    (begin
                       (print line)
                       (loop (read-line port))))))

     Both input and output ports can be piped:

          (let* ((proc (run-process "/usr/bin/dc" output: pipe: input: pipe:))
                 (inport (process-input-port proc))
                 (port (process-output-port proc)))
             (fprint inport "16 o")
             (fprint inport "16 i")
             (fprint inport "10")
             (fprint inport "10")
             (fprint inport "+ p")
             (flush-output-port inport)
             (let loop ((line (read-line port)))
                (if (eof-object? line)
          	  (close-input-port port)
          	  (begin
          	     (print line)
          	     (loop (read-line port))))))   -| 20

     _Note:_ The call to `flush-output-port' is mandatory in order to
     get the `dc' process to get its input characters.

     _Note:_ Thanks to Todd Dukes for the example and the suggestion of
     including it this documentation.

 -- bigloo procedure: process? obj
     Returns `#t' if OBJ is a process, otherwise returns `#f'.

 -- bigloo procedure: process-alive? process
     Returns `#t' if PROCESS is currently running, otherwise returns
     `#f'.

 -- bigloo procedure: close-process-ports command arg...
     Close the three ports associated with a process. In general the
     ports should not be closed before the process is terminated.

 -- bigloo procedure: process-pid process
     Returns an integer value which represents the Unix identification
     (PID) of the PROCESS.

 -- bigloo procedure: process-input-port process
 -- bigloo procedure: process-output-port process
 -- bigloo procedure: process-error-port process
     Return the file port associated to the standard input, output and
     error of PROCESS otherwise returns `#f'.  Note that the returned
     port is opened for reading when calling `process-output-port' or
     `process-error-port'.  It is opened for writing when calling
     `process-input-port'.

 -- bigloo procedure: process-wait process
     This function stops the current process until PROCESS completion.
     This function returns `#f' when PROCESS is already terminated. It
     returns `#t' otherwise.

 -- bigloo procedure: process-exit-status process
     This function returns the exit status of PROCESS if it is has
     finished its execution. It returns `#f' otherwise.

 -- bigloo procedure: process-send-signal process s
     Sends the signal whose integer value is S to PROCESS. Value of S
     is system dependent. The result of `process-send-signal' is
     undefined.

 -- bigloo procedure: process-kill process
     This function brutally kills PROCESS. The result of `process-kill'
     is undefined.

 -- bigloo procedure: process-stop process
 -- bigloo procedure: process-continue process
     Those procedures are only available on systems that support job
     control.  The function `process-stop' stops the execution of
     PROCESS and `process-continue' resumes its execution.

 -- bigloo procedure: process-list
     This function returns the list of processes which are currently
     running (i.e. alive).


File: bigloo.info,  Node: Socket,  Next: SSL,  Prev: Process,  Up: System Programming

4.7.4 Socket support
--------------------

Bigloo defines sockets, on systems that support them, as first class
objects.  Sockets permits processes to communicate even if they are on
different machines. Sockets are useful for creating client-server
applications.  The implementation and this documentation are, to a great
extent copies of the STk [Gallesio95] socket support.

 -- bigloo procedure: make-client-socket hostname port-number #!key
          (buffer #t) (timeout 0)
     `make-client-socket' returns a new socket object. This socket
     establishes a link between the running application listening on
     port PORT-NUMBER of HOSTNAME. If keyword argument BUFFER is `#f'
     then the input port associated with the socket is unbuffered. This
     is useful for socket clients connected to servers that do not emit
     #\Newline character after emissions. If optional argument BUFFERED
     is missing or is not to `#f' the input port uses a buffer. If the
     optional argument TIMEOUT is missing or is `0', the execution
     blocks until the connection is established. If the TIMEOUT is
     provided, the execution unblocks after TIMEOUT microseconds unless
     the connection is established.

     If the connection cannot be established, an `&io-error' is raised
     (see *note Errors and Assertions::).

     When a socket is used in unbufferized mode the characters
     available on the input port _must_ be read exclusively with
     `read-char' or `read-line'. It is forbidden to use `read' or any
     regular grammar.  This limitation is imposed by Rgc (see *note
     Regular Parsing::) that intrinsicly associates buffers with
     regular grammars. If the current Rgc implementation is improved on
     the coming version this restriction will be eliminated.

     Example:
          ;; open a client socket on port 80:
          (make-client-socket "www.inria.fr" 80)
          ;; open an unbufferized connection
          (make-client-socket "www.inria.fr" 80 :buffer #f)


 -- bigloo procedure: socket? obj
 -- bigloo procedure: socket-server? obj
 -- bigloo procedure: socket-client? obj
     Returns `#t' if OBJ is a socket, a socket server a socket client.
     Otherwise returns `#f'. Socket servers and socket clients are
     sockets.

 -- bigloo procedure: socket-hostname socket
     Returns a string which contains the name of the distant host
     attached to SOCKET. If SOCKET has been created with
     `make-client-socket' this procedure returns the official name of
     the distant machine used for connection. If SOCKET has been
     created with `make-server-socket', this function returns the
     official name of the client connected to the socket.  If no client
     has used yet the socket, this function returns `#f'.

 -- bigloo procedure: socket-host-address socket
     Returns a string which contains the IP number of the distant host
     attached to SOCKET. If SOCKET has been created with
     `make-client-socket' this procedure returns the IP number of the
     distant machine used for connection. If SOCKET has been created
     with `make-server-socket', this function returns the address of
     the client connected to the socket.  If no client has used yet the
     socket, this function returns `#f'.

 -- bigloo procedure: socket-local-address socket
     Returns a string which contains the IP number of the local host
     attached to SOCKET.

 -- bigloo procedure: socket-port-number socket
     Returns the integer number of the port used for SOCKET.

 -- bigloo procedure: socket-input socket
 -- bigloo procedure: socket-output socket
     Returns the file port associated for reading or writing with the
     program connected with SOCKET. If no connection has already been
     established, these functions return `#f'.

     The following example shows how to make a client socket. Here we
     create a socket on port 13 of the machine "`kaolin.unice.fr'"(1)
     (*note Socket-Footnote-1::):
          (let ((s (make-client-socket "kaolin.unice.fr" 13)))
            (print "Time is: " (read-line (socket-input s)))
            (socket-shutdown  s))

 -- bigloo procedure: make-server-socket #!key (name #f) #!optional
          (port 0)
     `make-server-socket' returns a new socket object.  The socket will
     be listening on the network interface NAME, either on the
     specified PORT, or on a port chosen by the system (usually the
     first port available on the network interface). The NAME can be an
     IP number as a string, or a host name, whose first IP address will
     be used (as returned by the name server lookup).

 -- bigloo procedure: socket-accept socket #!key (buffer #t) (errp #t)
     `socket-accept' waits for a client connection on the given SOCKET.
     It returns a `client-socket'.  If no client is already waiting for
     a connection, this procedure blocks its caller; otherwise, the
     first connection request on the queue of pending connections is
     connected to SOCKET. This procedure must be called on a server
     socket created with `make-server-socket'.  If keyword argument
     `buffer' is `#f' then the input port associated with the socket is
     unbuffered. This is useful for socket clients connected to servers
     that do not emit #\Newline character after emissions. If keyword
     argument `buffer' is missing or is not to `#f' the input port uses
     a buffer. The keyword argument ERRP is a boolean. The value `#t'
     means that if an error is raised it is signaled. Otherwise, it is
     omitted.

     _Note:_ When a socket is used in unbufferized mode the characters
     available on the input port _must_ be read exclusively with
     `read-char' or `read-line'. It is forbidden to use `read' or any
     regular grammar.  This limitation is imposed by Rgc (see *note
     Regular Parsing::) that intrinsicly associate buffers with regular
     grammars. If the current Rgc implementation is improved on the
     coming version this restriction will be suppressed.

     The following exemple is a simple server which waits for a
     connection on the port 1234(2) (*note Socket-Footnote-2::). Once
     the connection with the distant program is established, we read a
     line on the input port associated to the socket and we write the
     length of this line on its output port.
          (let* ((s (make-server-socket 1234))
                 (s2 (socket-accept s)))
            (let ((l (read-line (socket-input s2))))
              (fprint (socket-output s2) "Length is: " (string-length l))
              (flush-output-port (socket-output s2)))
            (socket-close s2)
            (socket-shutdown s))

 -- bigloo procedure: socket-close socket
     The function `socket-close' closes the connection established with
     a `socket-client'.

 -- bigloo procedure: socket-shutdown socket #!optional (close #t)
     `Socket-shutdown' shutdowns the connection associated to SOCKET.
     CLOSE is a boolean; it indicates if the socket must be closed or
     not, when the connection is destroyed. Closing the socket forbids
     further connections on the same port with the `socket-accept'
     procedure. Omitting a value for CLOSE implies the closing of
     socket.  The result of `socket-shutdown' is undefined.

 -- bigloo procedure: socket-down? socket
     Returns `#t' if SOCKET has been previously closed with
     `socket-shutdown'. It returns `#f' otherwise.

  Here is another example of making use of sockets:

     (define s1 (make-server-socket))
     (define s2 #unspecified)

     (dynamic-wind
        ;; Init: Launch an xterm with telnet running
        ;; on the s listening port and connect
        (lambda ()
           (run-process "/usr/X11R6/bin/xterm" "-display" ":0" "-e" "telnet" "localhost"
     		   (number->string (socket-port-number s1)))
           (set! s2 (socket-accept s1))
           (display #"\nWelcome on the socket REPL.\n\n> " (socket-output s2))
           (flush-output-port (socket-output s2)))

        ;; Action: A toplevel like loop
        (lambda ()
           (let loop ()
     	 (let ((obj (eval (read (socket-input s2)))))
     	    (fprint (socket-output s2) "; Result: " obj)
     	    (display "> " (socket-output s2))
     	    (flush-output-port (socket-output s2))
     	    (loop))))

        ;; Termination: We go here when
        ;;     -a: an error occurs
        ;;     -b: connection is closed
        (lambda ()
           (print #"Shutdown ......\n")
           (socket-close s2)
           (socket-shutdown s1)))

  Here is a second example that uses sockets. It implements a
client-server architecture and it uses unbufferized (see
`socket-accept') input ports.  

  First, here is the code of the client:

     (module client)

     (let* ((s (make-client-socket "localhost" 8080 #f))
            (p (socket-output s)))
        (display "string" p)
        (newline p)
        (display "abc" p)
        (flush-output-port p)
        (let loop ()
           (loop)))

  Then, here is the code of the server:

     (module server)

     (let* ((s (make-server-socket 8080))
            (s2 (socket-accept s #f)))
        (let ((pin (socket-input s2)))
           (let loop ()
              (display (read-char pin))
              (flush-output-port (current-output-port))
              (loop))))

  At, to conclude here the source code for a server waiting for multiple
consecutive connections:

     (define (main argv)
        (let ((n (if (pair? (cdr argv))
                     (string->integer (cadr argv))
                     10))
     	 (s (make-server-socket)))
           (print "s: " s)
           (let loop ((i 0))
              (if (<fx i n)
                  (let ((s2 (socket-accept s)))
     		(print "i: " i " " s2)
     		(print (read-line (socket-input s2)))
     		(socket-close s2)
                     (loop (+fx i 1)))
     	     (socket-shutdown s)))))

 -- bigloo procedure: host hostname
 -- bigloo procedure: hostinfo hostname
     Returns the IP number of HOSTNAME. When HOSTNAME is not found, the
     `io-unknown-host-error' exception is raided (see *note Errors and
     Assertions::).

     The function `hostinfo' possibly returns more information about the
     host. It returns an association list made out the information
     about the host. This list might contain a `name' entry, an
     `addresses' entry, and a `aliases' entry.

     Some back-ends (e.g., the C back-end) implements DNS caching. This
     may dramatically improve the performance of intensive networking
     applications.  DNS caching can be control by the means of two
     parameters: `bigloo-dns-enable-cache' and
     `bigloo-dns-cache-validity-timeout' (see *note Parameters::).


File: bigloo.info,  Node: Socket-Footnotes,  Up: Socket

  (1) Port 13 is generally used for testing: making a connection to it
permits to know the distant system's idea of the time of day.

  (2) Under Unix, you can simply connect to   listening socket with the
`telnet' command. With the given   example, this can be   achived by
typing the following command in a window shell:   `$ telnet localhost
1234'


File: bigloo.info,  Node: SSL,  Prev: Socket,  Up: System Programming

4.7.5 SSL
---------

* Menu:

* SSL Sockets::
* Certificates::
* Private Keys::

  Bigloo allows access to SSL sockets, certificates and private keys, in
order to build secure encrypted and/or signed communications.


File: bigloo.info,  Node: SSL Sockets,  Next: Certificates,  Up: SSL

4.7.5.1 SSL Sockets
...................

Bigloo defines SSL sockets, on systems that support them, as first
class objects. SSL Sockets permits processes to communicate even if
they are on different machines securely via encrypted connections. SSL
Sockets are useful for creating secure client-server applications.

 -- SSL library procedure: make-ssl-client-socket hostname port-number
          #!key (buffer #t) (timeout 0) (protocol 'sslv23) (cert #f)
          (pkey #f) (CAs '()) (accepted-certs #f)
     `make-ssl-client-socket' returns a new client socket object. This
     object satisfies the  `socket?' predicate (see *note Socket::) can
     be used in any context where a socket created by
     `make-client-socket' can be used.

     A SSL client socket establishes a link between the running
     application (client) and a remote application (server) listening
     on port PORT-NUMBER of HOSTNAME. If optional argument BUFFER is
     `#f' then the input port associated with the socket is unbuffered.
     This is useful for socket clients connected to servers that do not
     emit #\Newline character after emissions. If optional argument
     BUFFER is not to `#f' the input port uses a buffer. If the
     optional argument TIMEOUT is `0', the execution blocks until the
     connection is established. If the TIMEOUT is provided, the
     execution unblocks after TIMEOUT microseconds unless the
     connection is established. If the PROTOCOL option argument is
     given, it specifies the encryption protocol. Accepted values are
     `'sslv2', `'sslv3', `'sslv23' (alias `'ssl'), `'tls' (alias
     `'tlsv1') or `'dtls' (alias `'dtlsv1'). The default value is
     `'sslv23'.

     The SSL socket will sign the connection using the optional
     arguments CERT (for the certificate) and PKEY (for the private
     key).  The certificate CERT must be of type `certificate', and the
     private key PKEY must be of type `private-key'.  If any of those
     two arguments is given, they must both be given.  If those
     optional arguments are missing the connection will be encrypted
     but not signed from the client side.

     The CAS optional argument specifies the list of certificates to
     trust as CA (Certificate Authority) for the connection. It must be
     a list of values of type `certificate'. If the list is empty, the
     default list of trusted CA is used (set by the system). Note that
     giving a list of trusted certificates turns on the peer (server)
     certificate validation: an `&io-error' will be raised if the peer
     (server) certificate is not signed directly or indirectly by one
     of the certificates in CAS.

     The ACCEPTED-CERTS optional argument gives a list of certificate
     objects (of type `certificate') which are accepted as peer (server)
     certificate. If ACCEPTED-CERTS is `#f' then every peer (server)
     certificate is accepted (aside from eventual certificate
     validation).  If ACCEPTED-CERTS is a list, the peer (server)
     certificate must match one of the given certificates. Otherwise,
     an `&io-error' will be raised.

     If the connection cannot be established, an `&io-error' is raised
     (see *note Errors and Assertions::).

     When a socket is used in unbufferized mode the characters
     available on the input port _must_ be read exclusively with
     `read-char' or `read-line'. It is forbidden to use `read' or any
     regular grammar.  This limitation is imposed by Rgc (see *note
     Regular Parsing::) that intrinsicly associates buffers with
     regular grammars. If the current Rgc implementation is improved on
     the coming version this restriction will be eliminated.

     The function `make-ssl-client-socket' is defined in the SSL
     library.  A module that needs this facility must then use a
     `library' clause (see *note Modules::). The SSL library can also
     be loaded from the interpreter using the `library-load' function
     (see *note Bigloo Libraries::).

          (module imap
             (library ssl)
             (main main))

          (let* ((s (make-ssl-client-socket "localhost" 993))
                 (p (socket-output s)))
             (display "string" p)
             (newline p)
             (display "abc" p)
             (flush-output-port p)
             (let loop ()
                (loop)))


 -- SSL library procedure: client-socket-use-ssl! socket #!key
          (protocol 'sslv23) (cert #f) (pkey #f) (CAs '())
          (accepted-certs #f)
     Returns an SSL socket built from a socket obtained by
     `make-client-socket' (see *note Socket::). Depending on the
     implementation and back-end the returned socket may or may not be
     `eq?' to SOCKET.

 -- SSL library procedure: make-ssl-server-socket #!key (port 0) (name
          #f) (protocol 'sslv23) (cert #f) (pkey #f) (CAs '())
          (accepted-certs #f)
     `make-ssl-server-socket' returns a new server socket object which
     satisfies the `socket?' predicate and which can be used in any
     context where a socket created by `make-server-socket' can be used
     (see *note Socket::).

     A SSL server socket opens the port PORT on the current host NAME
     (the server), and allows remote applications (clients) to connect
     to it.  listening on port PORT-NUMBER of HOSTNAME. If the optional
     argument PORT is not given or is `0', the server socket will use
     the first availailable port number. If the optional argument NAME
     is given, the server socket will be bound to the network interface
     representing the given host name. If it is `#f' (the default) the
     socket will be bound on every local network interface.  If the
     PROTOCOL option argument is given, it specifies the encryption
     protocol. Accepted values are `'sslv2', `'sslv3', `'sslv23' (alias
     `'ssl'), `'tls' (alias `'tlsv1') or `'dtls' (alias `'dtlsv1'). The
     default value is `'sslv23'.

     The SSL socket will sign the connection using the optional
     arguments CERT (for the certificate) and PKEY (for the private
     key).  The certificate CERT must be of type `certificate', and the
     private key PKEY must be of type `private-key'.  If any of those
     two arguments is given, they must both be given.  If those
     optional arguments are missing the connection will be encrypted
     but not signed from the server side, which means the peer (client)
     will have to provide a certificate/private key pair to encrypt the
     connection, and that seldom happens. Typical SSL servers provide
     their certificate and private key.

     Note that since the peer (client) certificate is only known when we
     are accepting a client socket (with `socket-accept') the CAS and
     ACCEPTED-CERTS optional arguments are only checked during the
     accept operation of a server socket.

     The CAS optional argument specifies the list of certificates to
     trust as CA (Certificate Authority) for the connection. It must be
     a list of values of type `certificate'. If the list is empty, the
     default list of trusted CA is used (set by the system). Note that
     giving a list of trusted certificates turns on the peer (client)
     certificate validation: an `&io-error' will be raised if the peer
     (client) certificate is not signed directly or indirectly by one
     of the certificates in CAS when accepting the client socket.

     The ACCEPTED-CERTS optional argument gives a list of certificate
     objects (of type `certificate') which are accepted as peer (client)
     certificate. If ACCEPTED-CERTS is `#f' then every peer (client)
     certificate is accepted (aside from eventual certificate
     validation).  If ACCEPTED-CERTS is a list, the peer (client)
     certificate must match one of the given certificates. Otherwise,
     an `&io-error' will be raised when accepting the client socket.

     If the connection cannot be established, an `&io-error' is raised
     (see *note Errors and Assertions::).

     The function `make-ssl-server-socket' is defined in the SSL
     library.  A module that needs this facility must then use a
     `library' clause (see *note Modules::). The SSL library can also
     be loaded from the interpreter using the `library-load' function
     (see *note Bigloo Libraries::).

          (module secure-echo
             (library ssl))

          (let* ((cert (read-certificate "/etc/ssl/my_cert.crt"))
                 (pkey (read-private-key "/etc/ssl/my_key.pkey"))
                 (cas (read-pem-file "/etc/ssl/ca.cert"))
                 (s (make-ssl-server-socket 1055 :CAs cas :cert cert :pkey pkey))
                 (cs (socket-accept s))
                 (ip (socket-input cs))
                 (op (socket-output cs)))
             (let loop ((e (read i)))
                (when (not (eof-object? e))
                   (write e o)
                   (loop (read i))))
             (socket-close s))



File: bigloo.info,  Node: Certificates,  Next: Private Keys,  Prev: SSL Sockets,  Up: SSL

4.7.5.2 Certificates
....................

 -- SSL library procedure: read-certificate file
     Reads an X509 certificate stored in PEM format in the given FILE
     name.  If the file cannot be read, it raises an `&io-error'
     condition. Otherwise the certificate is returned.

 -- SSL library procedure: read-pem-file file
     Reads a list of  X509 certificate stored in PEM format in the
     given FILE name.  If the file cannot be read, it raises an
     `&io-error' condition. Otherwise the list of certificate contained
     in the file is returned.

 -- SSL library procedure: certificate? obj
     Returns `#t' if OBJ is an SSL certificate.  Otherwise returns `#f'.

 -- SSL library procedure: certificate-subject cert
     Returns the CommonName (CN) part of the subject of the given
     certificate.

 -- SSL library procedure: certificate-issuer cert
     Returns the CommonName (CN) part of the issuer of the given
     certificate.


File: bigloo.info,  Node: Private Keys,  Prev: Certificates,  Up: SSL

4.7.5.3 Private Keys
....................

 -- SSL library procedure: read-private-key file
     Reads a private key stored in PEM format in the given FILE name.
     If the file cannot be read, it raises an `&io-error' condition.
     Otherwise the private key is returned.

 -- SSL library procedure: private-key? obj
     Returns `#t' if OBJ is an SSL private key.  Otherwise returns `#f'.


File: bigloo.info,  Node: Date,  Next: Digest,  Prev: System Programming,  Up: Standard Library

4.8 Date
========

 -- bigloo procedure: date? obj
     Returns `#t' if and only if OBJ is a _date_ as returned by
     `make-date', `current-date', or `seconds->date'. It returns `#f'
     otherwise.

 -- bigloo procedure: make-date #!key (sec 0) (min 0) (hour 0) (day 0)
          (month 0) (year 1970) timezone (dst -1)
     Creates a `date' object from the integer values passed as argument.

     The argument TIMEZONE, if provided, is expressed in minute.

     Example:
          (write (make-date :sec 0 :min 22 :hour 17 :day 5 :month 2 :year 2003 :dst 0))
            -| #<date:Wed Feb  5 17:22:00 2003>

     The argument DST is either `-1' when the information is not
     available, `0' when daylight saving is disabled, `1' when daylight
     saving is enabled.

 -- bigloo procedure: date-copy date #!key sec min hour day month year
     Creates a new date from the argument DATE.

     Example:
          (date-copy (current-date) 1 0 0)


 -- bigloo procedure: current-date
     Returns a `date' object representing the current date.

 -- bigloo procedure: current-seconds
     Returns an `elong' integer representing the current date expressed
     in seconds.

 -- bigloo procedure: date->seconds
 -- bigloo procedure: seconds->date
     Convert from `date' and `elong'.

 -- bigloo procedure: date->string date
 -- bigloo procedure: date->utc-string date
 -- bigloo procedure: seconds->string elong
 -- bigloo procedure: seconds->utc-string elong
     Construct a textual representation of the date passed in argument

 -- bigloo procedure: date-second date
     Returns the number of seconds of a date, in the range `0...59'.

 -- bigloo procedure: date-minute date
     Returns the minute of a date, in the range `0...59'.

 -- bigloo procedure: date-hour date
     Returns the hour of a date, in the range `0...23'.

 -- bigloo procedure: date-day date
     Returns the day of a date, in the range `1...31'.

 -- bigloo procedure: date-wday date
 -- bigloo procedure: date-week-day date
     Returns the week day of a date, in the range `1...7'.

 -- bigloo procedure: date-yday date
 -- bigloo procedure: date-year-day date
     Returns the year day of a date, in the range `1...366'.

 -- bigloo procedure: date-month date
     Returns the month of a date, in the range `1...12'.

 -- bigloo procedure: date-year date
     Returns the year of a date.

 -- bigloo procedure: date-timezone date
     Returns the timezone of a date.

 -- bigloo procedure: date-is-dst date
     Returns `-1' if the information is not available, `0' is the date
     does not contain daylight saving adjustment, `1' if it contains a
     daylight saving adjustment.

 -- bigloo procedure: integer->second
     Converts a Bigloo fixnum integer into a second number.

 -- bigloo procedure: day-seconds
     Returns the number of seconds contained in one day.

 -- bigloo procedure: day-name int
 -- bigloo procedure: day-aname int
     Return the name and the abbreviated name of a week day.

 -- bigloo procedure: month-name int
 -- bigloo procedure: month-aname int
     Return the name and the abbreviated name of a month.

 -- bigloo procedure: date-month-length date
     Return the length of the month of DATE.

 -- bigloo procedure: leap-year? int
     Returns `#t' if and only if the year INT is a leap year.  Returns
     `#f' otherwise.

 -- bigloo procedure: rfc2822-date->date string
 -- bigloo procedure: rfc2822-parse-date input-port
     Parses RFC2822 string representing a date. These functions produce
     a Bigloo date object.

 -- bigloo procedure: date->rfc2822-date date
     Converts a Bigloo date into a string representation compliant with
     the RFC2822 format.


File: bigloo.info,  Node: Digest,  Prev: Date,  Up: Standard Library

4.9 Digest
==========

 -- bigloo procedure: base64-encode string [padding 64]
 -- bigloo procedure: base64-decode string
     Encodes (respec. decodes) a string into a base64 representation.

 -- bigloo procedure: base64-encode-port input-port output-port
          [padding 64]
 -- bigloo procedure: base64-decode-port input-port output-port
     Encodes (respec. decodes) an input port into a base64
     representation.

 -- bigloo procedure: pem-read-file file-name
 -- bigloo procedure: pem-decode-port input-port output-port
     Reads a PEM (Privacy Enhanced Mail) base64 encoded file.

 -- bigloo procedure: md5sum obj
 -- bigloo procedure: md5sum-string string
 -- bigloo procedure: md5sum-mmap mmap
 -- bigloo procedure: md5sum-file string
 -- bigloo procedure: md5sum-port input-port
     Computes MD5 message digest.

     The function `md5sum' dispatches over its argument and invokes the
     ad-hoc function. That is, it invokes `md5sum-string' if its
     argument is a string, `md5sum-mmap' if it is a mmap, `md5sum-port'
     if its argument is an input port.

 -- bigloo procedure: hmac-md5sum-string key string
     Computes the Hmac MD5 authentication:

          (hmac-md5sum-string (make-string 16 #a011) "Hi There")
            => "9294727a3638bb1c13f48ef8158bfc9d"

 -- bigloo procedure: cram-md5sum-string user key string
     Challenge-Response Authentication Mechanism as specified in RFC
     2195.

     The function `cram-md5sum-string' assumes that data is base64
     encoded.  The result is also base64 encoded.


File: bigloo.info,  Node: Pattern Matching,  Next: Fast search,  Prev: Standard Library,  Up: Top

5 Pattern Matching
******************

Pattern matching is a key feature of most modern functional programming
languages since it allows clean and secure code to be written.
Internally, "pattern-matching forms" should be translated (compiled)
into cascades of "elementary tests" where code is made as efficient as
possible, avoiding redundant tests; Bigloo's "pattern matching
compiler" provides this. The technique used is described in details in
[QueinnecGeffroy92], and the code generated can be considered optimal
(1) (*note Pattern Matching-Footnote-1::) due to the way this "pattern
compiler" was obtained.

  The "pattern language" allows the expression of a wide variety of
patterns, including:

   * Non-linear patterns: pattern variables can appear more than once,
     allowing comparison of subparts of the datum (through `eq?')

   * Recursive patterns on lists: for example, checking that the datum
     is a list of zero or more `a's followed by zero or more `b's.

   * Pattern matching on lists as well as on vectors and structures,
     and record types.


* Menu:

* Bigloo Pattern Matching Facilities::
* The Pattern Language::


File: bigloo.info,  Node: Pattern Matching-Footnotes,  Up: Pattern Matching

  (1) In the cases of pattern matching in lists and vectors, not in
structures for the moment.


File: bigloo.info,  Node: Bigloo Pattern Matching Facilities,  Next: The Pattern Language,  Up: Pattern Matching

5.1 Bigloo pattern matching facilities
======================================

Only two special forms are provided for this in Bigloo: `match-case'
and `match-lambda'.

 -- bigloo syntax: match-case key clause...
     The argument KEY may be any expression and each CLAUSE has the form

          (PATTERN S-EXPRESSION...)

     _Semantics: _ A `match-case' expression is evaluated as follows.
     KEY is evaluated and the result is compared with each successive
     pattern. If the pattern in some CLAUSE yields a match, then the
     expressions in that CLAUSE are evaluated from left to right in an
     environment where the pattern variables are bound to the
     corresponding subparts of the datum, and the result of the last
     expression in that CLAUSE is returned as the result of the
     `match-case' expression.  If no PATTERN in any CLAUSE matches the
     datum, then, if there is an `else' clause, its expressions are
     evaluated and the result of the last is the result of the whole
     `match-case' expression; otherwise the result of the `match-case'
     expression is unspecified.

     The equality predicate used is `eq?'.

          (match-case '(a b a)
             ((?x ?x) 'foo)
             ((?x ?- ?x) 'bar))
             => bar

  The following syntax is also available:

 -- bigloo syntax: match-lambda clause...
     It expands into a lambda-expression expecting an argument which,
     once applied to an expression, behaves exactly like a `match-case'
     expression.

          ((match-lambda
             ((?x ?x) 'foo)
             ((?x ?- ?x) 'bar))
           '(a b a))
             => bar


File: bigloo.info,  Node: The Pattern Language,  Prev: Bigloo Pattern Matching Facilities,  Up: Pattern Matching

5.2 The pattern language
========================

The syntax for <pattern> is:

     <pattern> ==>                _Matches:_

       <atom>                    the <atom>.
     | (`kwote' <atom>)            any expression `eq?' to `<atom>'.
     | (`and' <pat1> ... <patn>)   if all of `<patI>' match.
     | (`or' <pat1> ... ...<patn>) if any of `<pat1>' through `<patn>' matches.
     | (`not' <pat>)               if `<pat>' doesn't match.
     | (`?' <predicate>)           if `<predicate>' is true.
     | (<pat1> ... <patn>)       a list of n elements. Here, `...' is a
                                 meta-character denoting a finite repetition
                                 of patterns.
     | <pat> ...                 a (possibly empty) repetition
                                 of `<pat>' in a list.
     | #(<pat> ... <patn>)       a vector of N elements.
     | #{<struct> <pat> ... }    a structure.
     | `?'<id>                     anything, and binds `id' as a variable.
     | `?-'                        anything.
     | `??-'                       any (possibly empty) repetition of anything
                                 in a list.
     | `???-'                      any end of list.

_Remark: _ `and, or, not, check' and `kwote' must be quoted in order to
be treated as literals. This is the only justification for having the
`kwote' pattern since, by convention, any atom which is not a keyword
is quoted.

Explanations through examples
.............................

   * `?-' matches any s-expr

   * `a' matches the atom `'a'.

   * `?a' matches any expression, and binds the variable `a' to this
     expression.

   * `(? integer?)' matches any integer

   * `(a (a b))' matches the only list `'(a (a b))'.

   * `???-' can only appear at the end of a list, and always succeeds.
     For instance, `(a ???-)' is equivalent to `(a . ?-)'.

   * when occurring in a list, `??-' matches any sequence of anything:
     `(a ??- b)' matches any list whose `car' is `a' and last `car' is
     `b'.

   * `(a ...)' matches any list of `a''s, possibly empty.

   * `(?x ?x)' matches any list of length 2 whose `car' is  _eq_ to its
     `cadr'

   * `((and (not a) ?x) ?x)' matches any list of length 2 whose `car'
     is not _eq_ to `'a' but is _eq_ to its `cadr'

   * `#(?- ?- ???-)' matches any vector whose length is at least 2.

   * `#{foo (?- . ?-) (? integer?)}' matches any structure or record
     `foo' whose first and second fields are respectively a pair and an
     integer. You can provide only the fields you want to test. The
     order is not relevant.

  _Remark: _ `??-' and `...' patterns can not appear inside a vector,
where you should use `???-': For example, `#(a ??- b)' or `#(a...)' are
invalid patterns, whereas `#(a ???-)' is valid and matches any vector
whose first element is the atom `a'.


File: bigloo.info,  Node: Fast search,  Next: Structures and Records,  Prev: Pattern Matching,  Up: Top

6 Fast search
*************

This chapters details the Bigloo's API for fast string search
algorithms.

* Menu:

* Knuth - Morris - Pratt::


File: bigloo.info,  Node: Knuth - Morris - Pratt,  Up: Fast search

6.1 Knuth, Morris, and Pratt
============================

Bigloo supports an implementation of the _Knuth, Morris, and Pratt_
algorithm on strings and memory mapped area, *Note Memory mapped area::.

 -- bigloo procedure: kmp-table pattern
     This function creates a _kmp_-table used for fast search.

 -- bigloo procedure: kmp-mmap kmp-table mmap offset
 -- bigloo procedure: kmp-string kmp-table string offset
     This function searches the PATTERN described by KMP-TABLE in the
     memory mapped area MMAP (respec. in the STRING).  The search
     starts at OFFSET. If an occurrence is found, its position in the
     MMAP is returned. Otherwise `-1' is returned.

     For the sake of the example, here is a prototypal implementation of
     the Usenix command `grep':

          (define (main args)
             (cond
                ((null? (cdr args))
                 (fprintf (current-error-port) "Usage: grep STRING [FILE]...")
                 (exit 0))
                (else
                 (let ((t (kmp-table (cadr args))))
          	  (for-each (lambda (f) (grep-file t f)) (cddr args))))))

          (define (grep-file t file)
             (let* ((mm (open-mmap file read: #t write: #f))
          	  (ls (mmap-length mm)))
                (let loop ((o 0))
          	 (unless (>=fx o ls)
          	    (let ((n (kmp-mmap t mm o)))
          	       (when (>fx n 0)
          		  (print file ":" (mmap-line mm ls n))
          		  (loop (+fx n 1))))))
                (close-mmap mm)))

          (define (mmap-line mm ls n)
             (let ((b 0)
          	 (e (elong->fixnum ls)))
                ;; beginning
                (let loop ((i n))
          	 (when (>fx i 0)
          	    (if (char=? (mmap-ref mm i) #\Newline)
          		(set! b (+fx i 1))
          		(loop (-fx i 1)))))
                ;; end
                (let loop ((i n))
          	 (when (<fx i ls)
          	    (if (char=? (mmap-ref mm i) #\Newline)
          		(set! e i)
          		(loop (+fx i 1)))))
                (mmap-substring mm b (- e b))))


File: bigloo.info,  Node: Structures and Records,  Next: Object System,  Prev: Fast search,  Up: Top

7 Structures and Records
************************

Bigloo supports two kinds of enumerated types: the _structures_ and the
_records_. They offer similar facilities. Structures were pre-existing
to records and they are maintained mainly for backward compatiblity.
Recors are compliant with the Scheme request for implementation 9.

* Menu:

* Structures::
* Records (SRFI-9)::


File: bigloo.info,  Node: Structures,  Next: Records (SRFI-9),  Up: Structures and Records

7.1 Structures
==============

There is, in Bigloo, a new class of objects: structures, which are
equivalent to C `struct'.

 -- bigloo syntax: define-struct name field...
     This form defines a structure with name NAME, which is a symbol,
     having fields FIELD... which are symbols or lists, each list being
     composed of a symbol and a default value. This form creates
     several functions: creator, predicate, accessor and assigner
     functions. The name of each function is built in the following way:
        * Creator: `make-NAME'

        * Predicate: `NAME?'

        * Accessor: `NAME-FIELD'

        * Assigner: `NAME-FIELD-set!'

     Function `make-NAME' accepts an optional argument. If provided,
     all the slots of the created structures are filled with it. The
     creator named `name' accepts as many arguments as the number of
     slots of the structure. This function allocates a structure and
     fills each of its slots with its corresponding argument.

     If a structure is created using `make-NAME' and no initialization
     value is provided, the slot default values (when provided) are used
     to initialize the new structure. For instance, the execution of
     the program:

          (define-struct pt1 a b)
          (define-struct pt2 (h 4) (g 6))

          (make-pt1)
             => #{PT1 () ()}
          (make-pt1 5)
             => #{PT1 5 5}
          (make-pt2)
             => #{PT2 4 6}
          (make-pt2 5)
             => #{PT2 5 5}

 -- bigloo procedure: struct? obj
     Returns `#t' if and only if OBJ is a structure.


File: bigloo.info,  Node: Records (SRFI-9),  Prev: Structures,  Up: Structures and Records

7.2 Records (SRFI-9)
====================

Bigloo supports records has specified by SRFI-9. This section is a copy
of the SRFI-9 specification by Richard Kelsey. This SRFI describes
syntax for creating new data types, called record types.  A predicate,
constructor, and field accessors and modifiers are defined for each
record type.  Each new record type is distinct from all existing types,
including other record types and Scheme's predefined types.

 -- syntax: define-record-type expression...
     The syntax of a record-type definition is:

          <record-type-definition> ==> (`define-record-type' <type-name>
                                                   (<constructor-name> <field-tag> ...)
                                                   <predicate-name>
                                                   <field-spec> ...)
          <field-spec>             ==> (<field-tag> <accessor-name>)
                                     | (<field-tag> <accessor-name> <modifier-name>)
          <field-tag>              ==> <identifier>
          <accessor-name>          ==> <identifier>
          <predicate-name>         ==> <identifier>
          <modifier-name>          ==> <identifier>
          <type-name>              ==> <identifier>

     `Define-record-type' is generative: each use creates a new record
     type that is distinct from all existing types, including other
     record types and Scheme's predefined types. Record-type
     definitions may only occur at top-level (there are two possible
     semantics for `internal' record-type definitions, generative and
     nongenerative, and no consensus as to which is better).

     an instance of `define-record-type' is equivalent to the following
     definitions:

        * `<type-name>' is bound to a representation of the record type
          itself. Operations on record types, such as defining print
          methods, reflection, etc. are left to other SRFIs.

        * `<constructor-name>' is bound to a procedure that takes as
          many arguments as the re are `<field-tag>'s in the
          `(<constructor-name> ...)' subform and returns a new
          `<type-name>' record. Fields whose tags are listed with
          `<constructor-name>' have the corresponding argument as their
          initial value. The initial values of all other fields are
          unspecified.

        * `<predicate-name>' is a predicate that returns `#t' when
          given a value returned by `<constructor-name>' and `#f' for
          everything else.

        * Each `<accessor-name>' is a procedure that takes a record of
          type `<type-name>' and returns the current value of the
          corresponding field. It is an error to pass an accessor a
          value which is not a record of the appropriate type.

        * Each `<modifier-name>' is a procedure that takes a record of
          type `<type-name>' and a value which becomes the new value of
          the corresponding field; an unspecified value is returned. It
          is an error to pass a modifier a first argument which is not
          a record of the appropriate type.

     Records are disjoint from the types listed in Section 4.2 of R5RS.

     Seting the value of any of these identifiers has no effect on the
     behavior of any of their original values.

     The following

          (define-record-type pare
              (kons x y)
              pare?
              (x kar set-kar!)
              (y kdr))

     defines `kons' to be a constructor, `kar' and `kdr' to be
     accessors, `set-kar!' to be a modifier, and `pare?' to be a
     predicate for `pare's.

            (pare? (kons 1 2))        => #t
            (pare? (cons 1 2))        => #f
            (kar (kons 1 2))          => 1
            (kdr (kons 1 2))          => 2
            (let ((k (kons 1 2)))
              (set-kar! k 3)
              (kar k))                => 3


File: bigloo.info,  Node: Object System,  Next: Threads,  Prev: Structures and Records,  Up: Top

8 Object System
***************

Bigloo's object system is designed to be as simple as possible and
belongs to the CLOS [Bobrow et al. 88] object system family in that it
uses _classes_, _generic functions_ and _methods_. Its design has been
strongly influenced by C. Queinnec's MEROON [Queinnec93] It does not
include any meta object protocol.

* Menu:

* Class declaration::
* Creating and accessing objects::
* Generic functions::
* Widening and shrinking::
* Object library::
* Object serialization::
* Equality::
* Introspection::


File: bigloo.info,  Node: Class declaration,  Next: Creating and accessing objects,  Up: Object System

8.1 Class declaration
=====================

Classes are defined in a module declaration. A class declaration can
take place in a compiled or interpreted module. If a class declaration
takes place in a static module clause (see Section *note Module
Declaration::) its scope is limited to the current module but if it
takes place in an export module clause, its scope is extended to all
modules that import the current module. The syntax of a class
declaration is:

 -- bigloo module clause: class ident field ...
          <class> ==> `(class' <ident> <constructor>? <field>+`)'
               | `(final-class' <ident> <constructor>? <field>+`)'
               | `(wide-class' <ident> <constructor>? <field>+`)'
               | `(abstract-class' <ident> <constructor>? <field>+`)'
          <constructor> ==> `(' <expr> `)'
          <field> ==> <ident>
               | `(*' <ident>`)'
               | `('<ident> <field-prop>`)'
               | `(*' <ident> <field-prop>`)'
          <len> ==> <fixnum> | <string>
          <field-prop> ==> `read-only'
               | `(get' <bigloo-exp>`)'
               | `(set' <bigloo-exp>`)'
               | `(default' <bigloo-exp>`)'
               | `(info' <bigloo-exp>`)'
     
     A class is a Bigloo type and the class identifier is extracted
     from the <ident> of the class definition. If <ident> is also a
     <typed-ident>, the type part of this identifier denote the
     super-class of the class. If <ident> is a <IEEE-ident>, the
     super-class of the class is the root of the inheritance tree, the
     `object' class. This `object' class is the only pre-existing class.

     _Final classes_ can only be sub-classed by _wide classes_.  _Wide
     classes_ (only for compiled modules) can only inherit from _final
     classes_.  _abstract classes_ can't be instantiated.

     Wide-classes cannot be defined within the interpreter.

     The optional constructor is an expression that must evaluate to a
     one argument function. This function is automatically invoked each
     time a new class instance is created. The constructor is passed
     the fresh instance. If a class has not defined a constructor the
     super class' constructors are searched. The first constructor
     found is invoked.  A constructor may be a generic function with a
     method specified for one or more classes.

     A class field may be a _typed class field_ which is achieved by
     using a <typed-ident> instead of a <IEEE-ident> for the <ident>
     value.

     A class field defined as `(* ...)' is an indexed field and holds a
     sequence of items. The length of this sequence is defined at
     allocation time.

     Field marked with `read-only' declaration are immutables.

     `Default' declarations allow default field values. For indexed
     fields, the default value is the default value of each element of
     the sequence.

     For the means of an example, the traditional points and colored
     points can be defined as:
          (module example
             (static (abstract-class pt)
                     (class point::pt
                        x::double
                        y::double)
                     (class point-C::point
                        (color::string read-only))))

     We illustrate indexed fields, final and wide classes by the
     example:
          (module example
             (export (final-class person
                         (name::string (default "Jones"))
                         (sex read-only)
                         (* children::person))
                     (wide-class married-person::person
                         mate::person)))

     Fields may be virtual. A field is virtual as soon as its
     declaration contain a `get' attribute. Virtual fields have no
     physical implementation within the instance. When defining a
     virtual field, the class declaration implements a _getter_ and a
     _setter_ if that field is not a read only field. Access to the
     virtual field will rely on invocation of the user _getter_ and
     user _setter_. For instance:

          (module example
             (static (class complex
                        mag::double
                        angle::double
                        (real::double (get (lambda (p)
                                              (with-access::complex p (mag angle)
                                                 (* mag (cos angle)))))
                                      read-only)
                        (imag::double (get (lambda (p)
                                              (with-access::complex p (mag angle)
                                                 (* mag (sin angle)))))
                                      read-only))))

          (let ((p (instantiate::complex (mag 1.0) (angle 2.18))))
             (with-access::complex p (real imag)
                (print "real: " real)
                (print "imag: " imag)))

     Virtual fields cannot be associated default values. Virtual fields
     may not be indexed fields. If a virtual field is not provided with
     a setter it must be annotated as read only.

     `Info' declarations allow arbitrary user information field values.
     This value can be retrieved by introspection, by the means of the
     `class-field-info' introspection function.

     For the means of an example, with add to information to the slot of
     the point class.
          (module example
             (static (class point
                        (x::double (info '(range 0.0 10.0)))
                        (y::double (info '(range -1.0 1.0)))))



File: bigloo.info,  Node: Creating and accessing objects,  Next: Generic functions,  Prev: Class declaration,  Up: Object System

8.2 Creating and accessing objects
==================================

Bigloo automatically creates functions to allocate and manipulate
objects.  Let us suppose the class declaration:
     (class CLASS
        FIELD1::TYPE1
        (* FIELD2::TYPE2))

  Theses functions are:
   * A nil instance:
          (CLASS-nil::CLASS)

     This function returns the NIL pre-existing class instance. This
     instance plays the role of `void *' in C or `null' in Java. The
     value of each field is unspecified but correct with respect to the
     Bigloo type system. Each call to `CLASS-nil' returns the same
     object (in the sense of `eq?').

   * A creator:
          (make-CLASS::CLASS ::TYPE1 ::long ::TYPE2 ::TYPE3)

     This function allocates a fresh instance of CLASS and fills the
     field values with the argument. The length of the indexed field
     FIELD2 is given as argument of the function.

     Example:
          (class truc
             x::char
             (* y::bstring))

     The prototype of the allocation function is:
          (make-truc::truc x::char
                           y-len::long
                           y::bstring)

     The indexed values of the `y' and `z' fields will be set to the
     values of the formal parameters `y' and `z' respectively.

   * A filler:
          (fill-CLASS! ::CLASS ::TYPE1 ::long ::TYPE2 ::TYPE3)

     This function accepts the same arguments as the creator augmented
     with one allocated instance. This instance is filled up with the
     provided values.

   * A type checker:
          (CLASS?::bool OBJ::obj)

     This function returns `#t' if OBJ is an instance of CLASS or an
     instance of a sub-class of CLASS, otherwise, it returns `#f'.

   * Accessors and mutators:
          (CLASS-FIELD_1::TYPE_1 ::CLASS)
          (CLASS-FIELD_1-set!::obj ::CLASS ::TYPE_1)
          (CLASS-FIELD_2-len::long ::CLASS)
          (CLASS-FIELD_2-ref::TYPE_2 ::CLASS ::long)
          (CLASS-FIELD_2-set!::obj ::CLASS ::long ::TYPE_2)

     Declaring a field `read-only' prevents Bigloo from generating an
     associated `CLASS-FIELD_I-set!' function. The length of the
     indexed field is ` read-only'. Thus they do not have mutator
     functions.


  Some syntax helps with allocation and access to objects.

 -- bigloo syntax: with-access::CLASS obj (binding...) body
     A reference to any of the variables defined in as a BINDING is
     replaced by the appropriate field access form. This is true for
     both reference and assignment. A BINDING is either a symbol or a
     list of two symbols. In the first place, it denotes a field. In
     the second case, it denotes an aliases field.

     For instance:
          (with-access::point p (x (y1 y))
             (set! x (- x))
             (set! y1 (- y1)))
          is equivalent to:
          (begin
             (point-x-set! p (- (point-x p)))
             (point-y-set! p (- (point-y p))))

     When an indexed field is referenced inside the binding part of a
     `with-access' form, the functions that accesses and changes the
     fields are bound inside the body of the `with-access'. In addition,
     a variable reporting the length of the field is also bound. For a
     field FD, the getter function is `(FD-ref OFFSET)', the setter is
     `(FD-set! OFFSET VALUE)', the length variable is `FD-len'.  For
     instance:
          (with-access::truc o (y)
             (print "length: " y-len)
             (print "old y-ref(0): " (y-ref 0))
             (y-set! 0 "foo")
             (print "new y-ref(0): " (y-ref 0)))
          is equivalent to:
          (begin
             (print "length: " (truc-y-len o))
             (print "old y-ref(0): " (truc-y-ref o 0))
             (truc-y-set! o 0 "foo")
             (print "new y-ref(0): " (truc-y-ref o 0)))


 -- bigloo syntax: instantiate::CLASS (ident value)...
     This forms allocates object of class CLASS and fills the fields
     with values found in the list of parameters (note that field are
     explicitly named and that there is no ordering for field naming).
     Field values which are not provided in the parameter list must
     have been declared with a `default' value which is used to
     initialize the corresponding field.

     For instance:
          (make-point 0 0)
     is equivalent to:
          (instantiate::point (x 0) (y 0))

     Indexed field must be provided with exactly two values. The first
     is the length of the indexed field and the second is the default
     value of each element of the indexed field.

 -- bigloo syntax: co-instantiate ((VAR VALUE) ...) body
     This form is only available from compiled modules. In other words,
     it is not available from the interpreter. It permits the creation
     of recursive instances. It is specially useful for creating
     instances for which class declarations contain cyclic type
     references (for instance a class `c1' for a which a field is
     declared of class `c2' and a class `c2' for which a class is
     declared of type `c1'). The syntax of a `co-instantiate' form is
     similar to a `let' form. However the only legal VALUES are
     `instantiate' forms. The variables introduced in the binding of a
     `co-instantiate' form are bound in BODY. In addition, they are
     _partially_ bound in the VALUES expressions. In a VALUE position,
     a variable VAR can only be used to set the value of a field of an
     instantiated class. It cannot be used in any calculus. Example:

          (module obj-example
             (export (class c1 a b o2::c2)
                     (class c2 x y o1::c1)))

          (co-instantiate ((o1 (instantiate::c1
                                  (a 10)
                                  (b 20)
                                  (o2 o2)))
                           (o2 (instantiate::c2
                                  (x 10)
                                  (y 20)
                                  (o1 o1))))
             (+ (c2-x (c1-o2 o1)) (c2-y (c1-o2 x))))
                                                 => 30

 -- bigloo syntax: duplicate::CLASS obj (ident value)...
     This forms allocates an instance of class CLASS. The field values
     of the new object are picked up from the field values of the OLD
     object unless they are explicitly given in the parameter list.

     For instance:
          (with-access::point old (x)
             (make-point x 10))
     is equivalent to:
          (duplicate::point old (y 10))

     Indexed field must be provided with exactly two values. The first
     is the length of the indexed field and the second is the default
     value of each element of the indexed field.

     Here is an example of creations and mutations of a complex object:
          (module foo
             (export (class named-tab
                        name::string
                        (* els::int))))

          ;; a function that prints a named-tab
          (define (print-tab tab)
             (display* (named-tab-name tab) ": ")
             (let loop ((i (-fx (named-tab-els-len tab) 1)))
                (if (=fx i -1)
                    (newline)
                    (begin
                       (display* #\( i
                                 " "
                                 (named-tab-els-ref tab i)
                                 ") ")
                       (loop (-fx i 1))))))

          ;; we allocate a named-tab object with
          ;; 5 els, each of them initialized to 0
          (define a-tab (instantiate::named-tab
                           (name "example")
                           (els 5 0)))

          ;; we print its elements
          (print-tab a-tab)

          ;; we change the values of the indexed field
          ;; els by setting values from 0 to 4
          (let loop ((i (-fx (named-tab-els-len a-tab) 1)))
             (if (=fx i -1)
                 'done
                 (begin
                    (named-tab-els-set! a-tab i i)
                    (loop (-fx i 1)))))

          ;; we re-print it
          (print-tab a-tab)

     This will produce the following output:
          example: (4 0) (3 0) (2 0) (1 0) (0 0)
          example: (4 4) (3 3) (2 2) (1 1) (0 0)


File: bigloo.info,  Node: Generic functions,  Next: Widening and shrinking,  Prev: Creating and accessing objects,  Up: Object System

8.3 Generic functions
=====================

A generic function is a bag of specific functions known as methods. When
invoked on a Bigloo object, a generic function determines the class of
the discriminating variable (corresponding to the first argument of the
generic function) and invokes the appropriate method. Generic functions
implement single inheritance and each is defined using the
`define-generic' Bigloo syntax.

 -- bigloo syntax: define-generic (name arg...) default-body
     A generic function can be defined with a default body which will
     be evaluated if no method can be found for the discriminating
     variable. The default default-body signals an error.

  As an example, here is a possible definition of the `object-display'
generic function:

     (define-generic (object-display obj::object . op)
        (let ((port (if (pair? op)
                        (car op)
                        (current-output-port))))
           (display "#\|" port)
           (display (class-name (object-class obj)) port)
           (display "\|" port)))

  Methods can be defined to specialize a generic function and such
methods must have a compatible variable list. That is, the first
argument of the method must be a sub-type (i.e. belong to a sub-class)
of the first argument of the generic function. Other formal parameters
must be of same types. Moreover, the result type of the method must be
a sub-type of the result of the generic function.

 -- bigloo syntax: define-method (name arg...) body
     If there is no appropriate method, an error is signaled.

     Methods can use the form `(call-next-method)' to invoke the method
     that would have been called if not present. The
     `(call-next-method)' cannot be used out of method definition.
     example:
          (define-method (object-display p::person . op)
             (let ((port (if (pair? op)
                             (car op)
                             (current-output-port))))
                (fprint port "firstname : " (person-fname p))
                (fprint port "name      : " (person-name p))
                (fprint port "sex       : " (person-sex p))
                p))


File: bigloo.info,  Node: Widening and shrinking,  Next: Object library,  Prev: Generic functions,  Up: Object System

8.4 Widening and shrinking
==========================

Bigloo introduces a new kind of inheritance: _widening_. This allows an
object to be temporarily _widened_ (that is transformed into an object
of another class, a _wide-class_) and then _shrink-ed_ (that is
reshaped to its original class). This mechanism is very useful for
implementing short-term data storage. For instance, Bigloo compilation
passes are implemented using the _widening/shrinking_ mechanism. On
entry to a pass, objects are widened with the specific pass fields and,
on exit from a pass, objects are shrunk in order to forget the
information related to this pass.

  Only instances of _final classes_ can be widened and objects can only
be widened in order to become instances of _wide classes_.  Widening is
performed by the `widen!' syntax:

 -- bigloo syntax: widen!::WIDE-CLASS obj (id value) ...
     The object OBJ is widened to be instance of the wide class
     WIDE-CLASS. Fields values are either picked up from the parameter
     list of the `widen!' form or from the default values in the
     declaration of the wide class.

  Objects are shrunk using the `shrink!' syntax:

 -- bigloo syntax: shrink! obj

  Here is a first example:
     (module example
        (static (final-class point
                   (x (default 0))
                   (y (default 0)))
                (wide-class named-point::point name)))

     (define *point* (instantiate::point))

  Two classes have been declared and an instance `*point*' of `point'
has been allocated. For now, `*point*' is an instance of `point' but
not an instance of `named-point' and this can be checked by:
     (print (named? *point*))           ==> #t
     (print (named-point? *point*))     ==> #f

  Now, we _widen_ `*point*'...
     (let ((n-point (widen!::named-point *point*
                       (name "orig"))))

  And we check that now, `n-point' is an instance of `named-point'.
Since `named-point' is a subclass of `point', `n-point' still is an
instance of `point'.

     (print (named-point? n-point))  ==> #t
     (print (named? n-point))        ==> #t

  Widening affects the objects themselves. It does not operate any copy
operation. Hence, `*point*' and `n-point' are `eq?'.

     (print (eq? n-point *point*))   ==> #t

  To end this example, we _shrink_ `n-point' and check its class.
     (shrink! n-point)
     (print (named-point? *point*))) ==> #f

  Here is a more complex example:

  We illustrate widening and shrinking using our "wedding simulator".
First let us define three classes, `person' (for man and woman),
`married-woman' and `married-man':
     (module wedding
        (static (final-class person
                    name::string
                    fname::string
                    (sex::symbol read-only))
                (wide-class married-man::person
                    mate::person)
                (wide-class married-woman::person
                    maiden-name::string
                    mate::person)))
  As we can see people are allowed to change their name but not their
sex.

  The identity of a person can be printed as
     (define-method (object-display p::person . op)
        (with-access::person p (name fname sex)
           (print "firstname : " fname)
           (print "name      : " name)
           (print "sex       : " sex)
           p))

  A married woman's identity is printed by (we suppose an equivalent
method definition for married-man)
     (define-method (object-display p::married-woman . op)
        (with-access::married-woman p (name fname sex mate)
           (call-next-method)
           (print "married to: " (person-fname mate)
                                 " "
                                 (person-name mate))
           p))

  We create a person with the `birth' function:
     (define (birth name::string fname::string sex)
        [assert (sex) (memq sex '(male female))]
        (instantiate::person
           (name name)
           (fname fname)
           (sex sex)))

  We celebrate a wedding using the `get-married!' function:
     (define (get-married! woman::person man::person)
        (if (not (and (eq? (person-sex woman) 'female)
                      (eq? (person-sex man) 'male)))
            (error "get-married"
                   "Illegal wedding"
                   (cons woman man))
            (let* ((mname (person-name woman))
                   (wife  (widen!::married-woman woman
                           (maiden-name mname)
                           (mate man))))
               (person-name-set! wife (person-name man))
               (widen!::married-man man
                  (mate woman)))))

  We can check if two people are married by
     (define (couple? woman::person man::person)
        (and (married-woman? woman)
             (married-man? man)
             (eq? (married-woman-mate woman) man)
             (eq? (married-man-mate man) woman)))

  Now let us study the life a `Junior' `Jones' and `Pamela' `Smith'.
Once upon a time...
     (define *junior* (birth "Jones" "Junior" 'male))
     (define *pamela* (birth "Smith" "Pamela" 'female))

  Later on, they met each other and ... they got married:
     (define *old-boy-junior* *junior*)
     (define *old-girl-pamela* *pamela*)
     (get-married! *pamela* *junior*)

  This union can be checked:
     (couple? *pamela* *junior*)
        => #t

  We can look at the new identity of `*pamela*'
     (print *pamela*)
        -| name      : Jones
           firstname : Pamela
           sex       : FEMALE
           married to: Junior Jones

  But `*pamela*' and `*junior*' still are the same persons:
     (print (eq? *old-boy-junior* *junior*))   => #t
     (print (eq? *old-girl-pamela* *pamela*))  => #t

  Unfortunately all days are not happy days. After having been married
`*pamela*' and `*junior*' have divorced:
     (define (divorce! woman::person man::person)
        (if (not (couple? woman man))
            (error "divorce!"
                   "Illegal divorce"
                   (cons woman man))
            (let ((mname (married-woman-maiden-name
                           woman)))
               (begin
                  (shrink! woman)
                  (person-name-set! woman mname))
               (shrink! man))))

     (divorce! *pamela* *junior*)

  We can look at the new identity of `*pamela*'
     (print *pamela*)
        -| name      : Smith
           firstname : Pamela
           sex       : FEMALE

  And `*pamela*' and `*junior*' still are the same persons:
     (print (eq? *old-boy-junior* *junior*))   => #t
     (print (eq? *old-girl-pamela* *pamela*))  => #t


File: bigloo.info,  Node: Object library,  Next: Object serialization,  Prev: Widening and shrinking,  Up: Object System

8.5 Object library
==================

8.5.1 Classes handling
----------------------

No type denotes Bigloo's classes. These objects are handled by the
following library functions:

 -- bigloo procedure: find-class symbol
     Returns, if any, the class named SYMBOL.

 -- bigloo procedure: class? obj
     Returns `#t' if and only if OBJ is a class.

 -- bigloo procedure: class-super class
     Returns the _super-class_ of CLASS.

 -- bigloo procedure: class-subclasses class
     Returns the _subclasses_ of CLASS.

 -- bigloo procedure: class-name class
     Returns the name (a symbol) of CLASS.

 -- bigloo procedure: object-constructor class
     Returns CLASS's constructor.

 -- bigloo procedure: object-class object
     Returns the class that OBJECT belongs to.

8.5.2 Object handling
---------------------

 -- bigloo procedure: wide-object? object
     Returns `#t' if OBJECT is a wide object otherwise it returns `#f'.

 -- bigloo generic: object-display object [port]
     This generic function is invoked by `display' to display objects.

 -- bigloo generic: object-write object [port]
     This generic function is invoked by `write' to write objects.

 -- bigloo generic: object->struct object
 -- bigloo procedure: struct->object struct
     These functions converts objects into Scheme structures and
     vice-versa.

 -- bigloo generic: object-equal? object obj
     This generic function is invoked by `equal?' when the first
     argument is an instance of `object'.

 -- bigloo generic: object-hashnumber object
     This generic function returns an hash number of OBJECT.

 -- bigloo procedure: is-a? obj class
     Returns `#t' if OBJ belongs to CLASS otherwise it returns `#f'.


File: bigloo.info,  Node: Object serialization,  Next: Equality,  Prev: Object library,  Up: Object System

8.6 Object serialization
========================

Objects can be _serialized_ and _un-serialized_ using the regular
`string->obj' and `obj->string' functions. Objects can be stored on
disk and restored from disk by the use of the `output-obj' and
`input-obj' functions.

  In addition to this standard serialization mechanism, custom object
serializers and un-serializers can be specified by the means of the
`register-class-serialization!' function (see Section *note
Serialization::.


File: bigloo.info,  Node: Equality,  Next: Introspection,  Prev: Object serialization,  Up: Object System

8.7 Equality
============

Two objects can be compared with the `equal?' function. Two object are
equal if and only if they belong to a same class, all their field
values are equal and all their super class's field values are equal.


File: bigloo.info,  Node: Introspection,  Prev: Equality,  Up: Object System

8.8 Introspection
=================

Bigloo provides the programmer with some object introspection
facilities.  See section *note Object library:: for information on
classes and objects handling. Introspection facilities are, by default,
available for all classes. However, in order to shrink the code size
generation, it may be useful to disable class introspection. This
decision can be taken on a per class basis (i.e., one class may be
provided with introspection facilities while another one is not). The
compiler option `-fno-reflection' (see Chapter *note Compiler
Description::) prevents the compiler to generate the code required for
introspecting the classes defined in the compiled module.

 -- bigloo procedure: class-fields class
     Returns the a description of the fields of CLASS. This description
     is a list of field descriptions where each field description can
     be accessed by the means of the following library functions. The
     fields are those _directly_ defined in CLASS. That is
     `class-fields' does not return fields defined in super classes of
     CLASS.

 -- bigloo procedure: class-all-fields class
     Returns the a description of the fields of CLASS. This description
     is a list of field descriptions where each field description can
     be accessed by the means of the following library functions. By
     contrast with `class-fields', this function returns fields that
     are also defined in the super classes of CLASS.  in th

 -- bigloo procedure: find-class-field class symbol
     Returns the field named SYMBOL from class CLASS. Returns `#f' is
     such a field does not exist.

 -- bigloo procedure: class-field? obj
     Returns #t if OBJ is a class field descriptor. Otherwise returns
     #f.

 -- bigloo procedure: class-field-name field
     Returns the name of the FIELD. The name is a symbol.

 -- bigloo procedure: class-field-indexed? field
     Returns `#t' if the described field is indexed and `#f' otherwise.

 -- bigloo procedure: class-field-accessor field
     Returns a procedure of one argument. Applying this function to an
     object returns the value of the field described by FIELD.

 -- bigloo procedure: class-field-len-accessor field
     A one argument function is returned. Applying this function to an
     object returns the length value of the field described by field.
     It is an error to apply `class-field-len-accessor' to a
     non-indexed field.

 -- bigloo procedure: class-field-mutable? field
     Returns `#t' if the described field is mutable and `#f' otherwise.

 -- bigloo procedure: class-field-mutator field
     Returns a procedure of three, or two, arguments depending on
     whether the field is indexed or not. Applying this function to an
     object changes the value of the field described by FIELD. It is an
     error to apply `class-field-mutator' to an immutable field.

 -- bigloo procedure: class-field-info field
     Returns the information associated to FIELD (this the class
     declaration `info' attribute).

  For means of an example, here is a possible implementation of the
`equal?' test for objects:

     (define (object-equal? obj1 obj2)
        (define (class-field-equal? fd)
           (let ((get-value (class-field-accessor fd)))
              (if (not (class-field-indexed? fd))
                  (equal? (get-value obj1)
                          (get-value obj2))
                  (let* ((len (class-field-len-accessor
                               fd)))
                         (len1 (len obj1))
                         (len2 (len obj2)))
                     (and (=fx len1 len2)
                          (let loop ((i 0))
                             (cond
                                ((=fx i len1)
                                 #t)
                                ((equal?
                                  (get-value obj1 i)
                                  (get-value obj2 i))
                                 (loop (+fx i 1)))
                                (else
                                 #f))))))))
        (let ((class1 (object-class obj1))
              (class2 (object-class obj2)))
           (cond
              ((not (eq? class1 class2))
               #f)
              (else
               (let loop ((fields (class-fields class1))
                          (class  class1))
                  (cond
                     ((null? fields)
                      (let ((super (class-super class)))
                         (if (class? super)
                             (loop (class-fields super)
                                   super)
                             #t)))
                     ((class-field-equal? (car fields))
                      (loop (cdr fields) class))
                     (else
                      #f)))))))

 -- bigloo procedure: class-creator class
     Returns the creator for CLASS. The creator is a function for which
     the arity depends on the number of slots the class provides (see
     Section *note Creating and accessing objects::).

     When an instance is allocated by the means of the `class-creator',
     as for direct instantiation, the class constructor is
     _automatically_ invoked.  Example:
          (module foo
             (main main)
             (static (class c1 (c1-constructor))))

          (define c1-constructor
             (let ((count 0))
                (lambda (inst)
          	 (set! count (+ 1 count))
          	 (print "creating instance: " count)
          	 inst)))

          (define (main argv)
             (let ((o1 (instantiate::c1))
          	 (o2 (instantiate::c1))
          	 (o3 ((class-creator c1))))
                'done))
             -| creating instance: 1
                creating instance: 2
                creating instance: 3

     For each indexed field, two values must be sent to the function
     returned by `class-creator'. The first value denotes the size of
     the indexed field. The second value denotes the initial values of
     the fields. For instance:
          (module example
             (export (class point x y (* z))))

          (let ((create (class-creator point)))
             (print (create 10 23 5 3)))

     Produces   -| #|POINT [X: 10] [Y: 23] [Z: 3 3 3 3 3]|

 -- bigloo procedure: class-nil class
     Returns the NIL creator for CLASS.

 -- bigloo procedure: class-predicate class
     Returns the predicate for CLASS. This predicate returns `#t' when
     applied to object of type CLASS. It returns `#f' otherwise.


File: bigloo.info,  Node: Threads,  Next: Regular Parsing,  Prev: Object System,  Up: Top

9 Threads
*********

Bigloo supports multithreaded programming. Two different libraries
programming are available. The first one, the _Fair Thread_ (see
Section *note Fair Threads::), enables, simple, easy to develop and to
maintain code. The second one, the Posix Thread (see Section *note
Posix Threads::) enables more easily to take benefit of the actual
parallelism that is now available on stock hardware. Because it is
easier to program with `fthread' than with `pthread', we strongly
recommend to use the former as much as possible and leave the former
for specially demanding applications. Both libraries are described in
this chapter.

* Menu:

* Thread Common Functions::
* Fair Threads::
* Posix Threads::


File: bigloo.info,  Node: Thread Common Functions,  Next: Fair Threads,  Up: Threads

9.1 Thread Common Functions
===========================

This section describes the functions that are available independently
of the multi-threading library.

 -- SRFI-18 function: mutex? OBJ
 -- SRFI-18 function: make-mutex [NAME]
 -- SRFI-18 function: mutex-name MUTEX
 -- SRFI-18 function: mutex-specific MUTEX
 -- SRFI-18 function: mutex-specific-set! MUTEX OBJ
 -- SRFI-18 function: mutex-state MUTEX
 -- SRFI-18 function: mutex-lock! MUTEX [TIMEOUT [THREAD]]
 -- SRFI-18 function: mutex-unlock! MUTEX
          (let ((m (make-mutex)))
             (thread-start!
              (make-thread (lambda ()
                              (let loop ()
                                 (if (mutex-lock! m 0)
                                     (begin
                                        (display "locked")
                                        (mutex-unlock! m))
                                     (begin
                                        (thread-yield!)
                                        (loop))))))))
            -| locked

          (let ((res '()))
             (define (mutex-lock-recursively! mutex)
                (if (eq? (mutex-state mutex) (current-thread))
                    (let ((n (mutex-specific mutex)))
                       (mutex-specific-set! mutex (+ n 1)))
                    (begin
                       (mutex-lock! mutex)
                       (mutex-specific-set! mutex 0))))
             (define (mutex-unlock-recursively! mutex)
                (let ((n (mutex-specific mutex)))
                   (if (= n 0)
                       (mutex-unlock! mutex)
                       (mutex-specific-set! mutex (- n 1)))))
             (thread-start!
              (make-thread
               (lambda ()
                  (let ((m (make-mutex)))
                     (mutex-lock-recursively! m)
                     (mutex-lock-recursively! m)
                     (mutex-lock-recursively! m)
                     (set! res (cons (mutex-specific m) res))
                     (mutex-unlock-recursively! m)
                     (mutex-unlock-recursively! m)
                     (mutex-unlock-recursively! m)
                     (set! res (cons (mutex-specific m) res))))))
             res)
            => (0 2)

 -- Bigloo function: with-lock mutex thunk
     The function WITH-LOCK evaluates the body of the THUNK.  The mutex
     MUTEX is acquired and released before THUNK gets invoked.  The
     function WITH-LOCK might be implemented as:

          (define (with-lock mutex thunk)
             (mutex-lock! mutex)
             (unwind-protect
                (thunk)
                (mutex-unlock! mutex)))

 -- SRFI-18 function: condition-variable? OBJ
 -- SRFI-18 function: make-condition-variable [NAME]
 -- SRFI-18 function: condition-variable-name CV
 -- SRFI-18 function: condition-variable-specific CV
 -- SRFI-18 function: condition-variable-specific-set! CV OBJ
 -- SRFI-18 function: condition-variable-wait! CV MUTEX
 -- SRFI-18 function: condition-variable-signal! CV
 -- SRFI-18 function: condition-variable-broadcast! CV
          (let ((res 0))
             (define (make-semaphore n)
                (vector n (make-mutex) (make-condition-variable)))
             (define (semaphore-wait! sema)
                (mutex-lock! (vector-ref sema 1))
                (let ((n (vector-ref sema 0)))
                   (if (> n 0)
                       (begin
                          (vector-set! sema 0 (- n 1))
                          (mutex-unlock! (vector-ref sema 1)))
                       (begin
                          (mutex-unlock! (vector-ref sema 1) (vector-ref sema 2))
                          (semaphore-wait! sema)))))
             (define (semaphore-signal-by! sema increment)
                (mutex-lock! (vector-ref sema 1))
                (let ((n (+ (vector-ref sema 0) increment)))
                   (vector-set! sema 0 n)
                   (if (> n 0)
                       (condition-variable-broadcast! (vector-ref sema 2)))
                   (mutex-unlock! (vector-ref sema 1))))
             (let ((sema (make-semaphore 10)))
                (let ((t1 (thread-start! (make-thread
                                          (lambda ()
                                             (semaphore-wait! sema)
                                             (set! res (current-time))))))
                      (t2 (thread-start! (make-thread
                                          (lambda ()
                                             (let loop ((n 10))
                                                (if (> n 0)
                                                    (begin
                                                       (semaphore-signal-by! sema 1)
                                                       (thread-yield!)
                                                       (loop (- n 1))))))))))
                   (scheduler-start!)
                   res)))
            => 2

 -- Bigloo function: thread-parameter ident
     Returns the value of the parameter IDENT in the current thread. If
     no value is bound to this parameter, `#f' is returned.

     A thread parameter is implemented by a chunk of memory specific to
     each thread. All threads are created with an empty set of
     parameters.

 -- Bigloo function: thread-parameter-set! ident value
     Associates a VALUE to a parameter named IDENT.


File: bigloo.info,  Node: Fair Threads,  Next: Posix Threads,  Prev: Thread Common Functions,  Up: Threads

9.2 Threads
===========

Bigloo supports fair threads (see Section *note Thread::), a
specification of cooperative threads. In this framework a thread must
explicitly or implicitly _yield_ the processor to the scheduler (see
Section *note Scheduler::). Explicit cooperation is achieved by library
functions such as `thread-yield!' or `thread-sleep!'. The scheduler
does not preempt a running thread to allocate the processor to another
waiting thread. Fair threads have two drawbacks over preemptive threads:

   * Cooperative threads are not skilled to benefit of multi processors
          platforms.

   * Single threads programs must be adapted in order to be ran
     concurrently.

  On the other hand, Fair threads have advantages that make them
suitable for a high level programming language such as Scheme:

   * Fair threads have a strong and well defined semantic. Multi
     threaded       programs using Fair threads are _deterministic_
     thus programs       that deploy Fair threads are _predictable_.

   * Fair threads are easier to program with because they hide most the
          of the concurrent programming pitfalls. In particular, since
     Fair       threads enforce a strong synchronization, there
     is no need to deploy techniques such as _mutex_, _semaphore_
     or _condition variables_.

* Menu:

* Introduction::
* Fair Threads Api::
* SRFI-18::

  This whole chapter has been written in collaboration with Frédéric
Boussinot. It uses materials on Fair threads that can be found at
`http://www-sop.inria.fr/mimosa/rp/FairThreads/html/FairThreads.html'.


File: bigloo.info,  Node: Introduction,  Next: Fair Threads Api,  Up: Fair Threads

9.2.1 Introduction to Fair Threads
----------------------------------

Fair threads are cooperative threads run by a fair scheduler which
gives them equal access to the processor. Fair threads can communicate
using broadcast events. Their semantics does not depends on the
executing platform. Fine control over fair threads execution is
possible allowing the programming of specific user-defined scheduling
strategies.

  Contrary to standard sequential programming where the processor
executes a single program, in concurrent programming the processor is a
shared resource which is dispatched to several programs. The term
_concurrent_ is appropriate because programs can be seen as
concurrently competing to gain access to the processor, in order to
execute.

  Threads are a basic mean for concurrent programming, and are widely
used in operating systems. At language level, threads offer a way to
structure programs by decomposing systems in several concurrent
components; in this respect, threads are useful for modularity.

  However, threads are generally considered as low-level primitives
leading to over-complex programming. Moreover, threads generally have
loose semantics, in particular depending on the underlying executing
platform; to give them a precise semantics is a difficult task, and
this is a clearly identified problem to get portable code.

  Bigloo proposes a new framework with clear and simple semantics, and
with an efficient implementation. In it, threads are called _fair_;
basically a fair thread is a cooperative thread executed in a context
in which all threads always have equal access to the processor. Fair
threads have a deterministic semantics, relying on previous work
belonging to the so-called reactive approach.


File: bigloo.info,  Node: Fair Threads Api,  Next: SRFI-18,  Prev: Introduction,  Up: Fair Threads

9.2.2 Fair Threads Api
----------------------

* Menu:

* Thread::
* Scheduler::
* Signal::

  Bigloo uses a set of _primitive_ functions to create, run and handle
thread. For the sake of standardization the name and semantic of
SRFI-18 (Multithreading support) has been used. This section presents
only the mandatory functions to program with Fair threads in Bigloo. The
Section *note SRFI-18:: presents the functions that are not necessary
to Bigloo but supported for compliance with SRFI-18.


File: bigloo.info,  Node: Thread,  Next: Scheduler,  Up: Fair Threads Api

9.2.2.1 Thread
..............

 -- SRFI-18 function: current-thread
     Returns the current thread.

 -- SRFI-18 function: thread? OBJ
     Returns `#t' if OBJ is a thread, otherwise returns `#f'.

 -- SRFI-18 function: make-thread THUNK [NAME]
     Returns a new thread which is not started yet. The body of the
     thread is the body of the procedure THUNK. The optional argument
     NAME can be use to identify the thread. It can be any Bigloo value.

          (make-thread (lambda () (print 1) (thread-yield!) (print 2)) 'my-thread)

 -- SRFI-18 function: thread-start! THREAD [SCHEDULER]
     Runs a thread created with `make-thread'. If SCHEDULER is
     provided, the THREAD is started this particular scheduler.
     Otherwise, it is started in the current scheduler (see Section
     *note Scheduler::).  Threads are started at the beginning of
     _reactions_ (see Section *note Scheduler::).

 -- SRFI-18 function: thread-name THREAD
     Returns the name of the THREAD that has been passed to
     `make-thread'.

 -- SRFI-18 function: thread-specific THREAD
 -- SRFI-18 function: thread-specific-set! THREAD OBJ
     Returns and sets value in the specific field of the THREAD. If no
     value has been set, `thread-specific' returns an unspecified value.

          (let ((t (make-thread (lambda ()
                                   (print (thread-specific (current-thread)))))))
             (thread-specific-set! t 'foo)
             (thread-start! t)) -| foo

 -- Bigloo function: thread-cleanup THREAD
 -- Bigloo function: thread-cleanup-set! THREAD FUN
     Associates a cleanup function to a thread. The cleanup function is
     called with the thread itself. The cleanup function is executed in
     a context where `current-thread' is the thread owning the cleanup
     function.

          (let ((t (make-thread (lambda () 'done) 'foo)))
             (thread-cleanup-set! t (lambda (v) (print (thread-name (current-thread))
          					     ", exit value: " v)))
             (thread-start! t)) -| foo, exit value: done

 -- SRFI-18 function: thread-yield!
     The current thread _cooperates_. That is, it is suspend for the
     _reaction_ and the scheduler selects a new thread to be resumed.
     The scheduler resumes the next avaliable thread. If there is only
     one thread started in the scheduler, the same thread is resumed.
     A _reaction_ correspond to the invocation of a `scheduler-react!'
     call (see Section *note Scheduler::).


 -- SRFI-18 function: thread-sleep! TIMEOUT
     The current thread _cooperates_ during _exactly_ TIMEOUT
     _reactions_ (see *note Scheduler::). It is suspended and the
     scheduler selects a new thread to be resumed. If there is only one
     thread started in the scheduler, the same thread will be resumed.

          (let ((t1 (make-thread
                     (lambda () (thread-sleep! 2) (display 'foo))))
                (t2 (make-thread
                     (lambda () (let loop ((n 1))
                                   (display n)
                                   (thread-yield!)
                                   (if (< n 5)
                                       (loop (+ n 1))))))))
             (thread-start! t1)
             (thread-start! t2)
             (scheduler-start!)) -| 12foo34

 -- SRFI-18 function: thread-terminate! THREAD
     Terminates THREAD at the end of the current reaction.

 -- SRFI-18 function: thread-join! THREAD [TIMEOUT [TIMEOUT-VAL]]
     The current thread waits until the THREAD terminates or until the
     TIMEOUT is reached (when supplied). If the TIMEOUT is reached,
     `thread-join!' returns TIMEOUT-VAL. If THREAD terminates,
     `thread-join!' returns the end-result of the THREAD or the
     end-exception if that thread terminates abnormally.

     If several threads wait for the termination of the same thread,
     they are all notified of the termination during the current
     reaction.

          (let* ((t1 (thread-start!
          	    (make-thread (lambda ()
          			    (thread-sleep! 3)
          			    'foo))))
                 (t2 (thread-start!
          	    (make-thread (lambda ()
          			    (print "t1: " (thread-join! t1 1))))))
                 (t3 (thread-start!
          	    (make-thread (lambda ()
          			    (print "t2: " (thread-join! t1 2 'bar))))))
                 (t3 (thread-start!
          	    (make-thread (lambda ()
          			    (print "t3: " (thread-join! t1))))))
                 (t4 (thread-start!
          	    (make-thread (lambda ()
          			    (print "t4: " (thread-join! t1)))))))
             (scheduler-start!))
             -| t1: #|%uncaught-exception [reason: (exception . join-timeout)]|
                t2: bar
                t3: foo
                t4: foo

 -- Bigloo function: thread-suspend! THREAD
 -- Bigloo function: thread-resume! THREAD
     Suspends/resumes the THREAD at the end of reaction. While suspended
     a thread is not eligible to get the processor by the scheduler.

 -- Bigloo function: thread-await! SIGNAL [TIMEOUT]
     Blocks the thread until SIGNAL has been broadcast or until TIMEOUT
     is elapsed. The function `thread-await!' returns the value
     associated with the previous emissions of the signal that took
     place during the reaction.

          (let ((t1 (thread-start!
                     (make-thread
                      (lambda ()
                       (display (thread-await! 'foo))
                       (display (thread-await! 'bar))))))
                (t2 (thread-start!
                     (make-thread
                      (lambda ()
                       (broadcast! 'foo 'val1-foo)
                       (broadcast! 'foo 'val2-foo)))))
                (t3 (thread-start!
                     (make-thread
                      (lambda ()
                       (thread-sleep! 2)
                       (broadcast! 'bar 'val-bar))))))
             (let loop ((n 1))
                (display n)
                (scheduler-react! (default-scheduler))
                (loop (+ n 1))))
            -| 1val2-foo23val-bar456...

     The function `thread-await!' cannot be used to intercept all the
     signals broadcasted during a reaction. This is illustrated by the
     following example were obviously `thread-await!' cannot intercept
     the emission of the signal:

          (thread-start! (make-thread (lambda ()
                                         (tread-await! 'foo)
                                         (broadcast! 'foo 1))))
          (thread-start! (make-thread (lambda ()
                                         (broadcast! 'foo 2))))

 -- Bigloo function: thread-get-values! SIGNAL
     Terminates the instant for the thread (as `thread-yield!') and
     returns, hence at the next instant, all the values associated with
     broadcast SIGNAL (see Section *note Signal::) during the previous
     scheduler reaction (see Section *note Scheduler::).

     Example:
          (thread-start! (make-thread
                            (lambda ()
                               (for-each print (thread-get-values! 'foo)))))
          (thread-start! (make-thread
                            (lambda ()
                               (broadcast! 'foo 1)
                               (broadcast! 'foo 'foo)
                               (broadcast! 'foo "blabla"))))
             -| 1
                foo
                blabla

     Example:
          (let ((t1 (thread-start!
                     (make-thread
                      (lambda ()
                         (for-each print (thread-get-values! 'foo)))
                      't1)))
                (t2 (thread-start!
                     (make-thread
                      (lambda ()
                         (broadcast! 'foo (current-thread))
                         (thread-yield!)
                         ;; this second broadcast won't be intercepted
                         ;; because it occurs during the next reaction
                         (broadcast! 'foo (current-thread)))
                      't2)))
                (t3 (thread-start!
                     (make-thread
                      (lambda ()
                         (broadcast! 'foo (current-thread))
                         (broadcast! 'foo (current-thread)))
                      't3))))
             (scheduler-start!))
             -| #<thread:t2>
                #<thread:t3>
                #<thread:t3>

 -- Bigloo function: thread-await-values! SIGNAL [TIMEOUT]
     This blocks the current thread until SIGNAL has been broadcast.
     It then returns, at the next instant, all the values associated
     with all the broadcasts that took place during the instant.  It
     can be defined as:

          (define (thread-await-values! signal . tmt)
             (apply thread-await! signal tmt)
             (thread-get-values signal))

 -- Bigloo function: thread-await*! SIGNALS [TIMEOUT]
     Wait for one of a list of signals. The function `thread-await*!'
     can be compared to the Unix `select' function. The argument
     SIGNALS is a list of signal identifier. The function
     `thread-await*!' blocks the current thread until one of the signal
     in the list SIGNALS is broadcast or until the optional numerical
     argument TIMEOUT is elapsed. If the thread unblocks because the
     timeout is elapsed, `thread-await*!' returns `#f'. Otherwise it
     returns two values that have to be collected with
     `multiple-value-bind' (see *note Control Features::). The first
     one is the value of the broadcast signal. The second one is the
     broadcast signal.

     Example:
          (let ((res #f))
             (thread-start!
              (make-thread (lambda ()
                              (let ((sig* (list 'foo 'bar)))
                                 (multiple-value-bind (val1 sig1)
                                    (thread-await*! sig*)
                                    (multiple-value-bind (val2 sig2)
                                       (thread-await*! sig*)
                                       (thread-yield!)
                                       (multiple-value-bind (val3 sig3)
                                          (thread-await*! sig*)
                                          (set! res (list sig1 sig2 sig3)))))))))
             (thread-start!
              (make-thread (lambda ()
                              (thread-sleep! 2)
                              (broadcast! 'foo 1))))
             (thread-start!
              (make-thread (lambda ()
                              (thread-sleep! 3)
                              (broadcast! 'bar 2))))
             (scheduler-start!)
             res)
            => '(foo foo bar)

     A second example using timeouts:
          (let ((res #f))
             (thread-start!
              (make-thread (lambda ()
                              (let ((sig* (list 'foo 'bar)))
                                 (multiple-value-bind (val1 sig1)
                                    (thread-await*! sig* 1)
                                    (thread-yield!)
                                    (multiple-value-bind (val2 sig2)
                                       (thread-await*! sig* 1)
                                       (thread-yield!)
                                       (multiple-value-bind (val3 sig3)
                                          (thread-await*! sig* 2)
                                          (set! res (list sig1 sig2 sig3)))))))))
             (thread-start!
              (make-thread (lambda ()
                              (thread-sleep! 2)
                              (broadcast! 'foo 1))))
             (thread-start!
              (make-thread (lambda ()
                              (thread-sleep! 3)
                              (broadcast! 'bar 2))))
             (scheduler-start!)
             res)
            => '(#f foo bar)

 -- Bigloo function: thread-get-values*! SIGNALS
     Terminates the instant for the thread (as `thread-yield!') and
     returns, hence at the next instant, all the values associated with
     all broadcast SIGNALS (see Section *note Signal::) during the
     previous scheduler reaction (see Section *note Scheduler::). The
     function `thread-get-values*!' returns an _alist_ made of the
     scanned signal and their values. That is the length of the returns
     list is the length of the list SIGNALS. If a signal of the list
     SIGNALS has not been broadcast, its associated entry the list
     returned by `thread-get-values*!' has an empty `cdr'.

     Example:
          (let ((s1 'foo)
                (s2 'bar)
                (s3 'gee)
                (res #f))
             (thread-start!
              (make-thread (lambda ()
                              (thread-sleep! 2)
                              (broadcast! 'foo (current-time))
                              (broadcast! 'bar 0))))
             (thread-start!
              (make-thread (lambda ()
                              (thread-await*! (list s1 s2 s3))
                              (set! res (thread-get-values*! (list s1 s2 s3))))))
             (thread-start!
              (make-thread (lambda ()
                              (thread-sleep! 2)
                              (broadcast! 'bar (current-time)))))
             (scheduler-start!)
             res)
            => ((foo 3) (bar 3 0) (gee))

     Used with asynchronous signal, the functions `thread-await*!' and
     `thread-get-values*!' can be used to read concurrently, in a non
     blocking way, several files.

 -- Bigloo function: thread-await-values*! SIGNALS [TIMEOUT]
     This blocks the current thread until at least one of SIGNALS has
     been broadcast. It then returns, at the next instant, all the
     values associated with all the broadcasts that took place during
     the instant. It can be defined as:

          (define (thread-await-values*! signal . tmt)
             (apply thread-await*! signal tmt)
             (thread-get-values*! signal))


File: bigloo.info,  Node: Scheduler,  Next: Signal,  Prev: Thread,  Up: Fair Threads Api

9.2.2.2 Scheduler
.................

 -- Bigloo function: make-scheduler [ENVS]
     Creates a new scheduler. The optional arguments ENVS are _fair
     thread environments_ which will be defined in forthcoming Bigloo
     releases.

 -- Bigloo function: scheduler? OBJ
     Returns `#t' if OBJ is a scheduler. Otherwise returns `#f'.

 -- Bigloo function: current-scheduler
     Returns the current scheduler. The current scheduler is the
     scheduler used in the last call to `scheduler-react!' or
     `scheduler-start!'.  It always exists a current scheduler. That
     is, it is optional for an application to create a scheduler.

 -- Bigloo function: scheduler-react! [SCHEDULER]
     Executes all the treads started (see `thread-start!', Section
     *note Thread::) in the scheduler until all the threads are
     blocked. A thread is blocked if the has explicitly yield the
     processor (`thread-yield!' and `thread-sleep!') or because it is
     waiting a signal (`thread-await!'). A thread can be selected
     several times during the same reaction.  The function
     `scheduler-react!' returns a symbol denoting the _state_ of the
     scheduler. The possible states are:

        * `ready' The Scheduler is ready to execute some threads.

        * `done' All the threads started in the scheduler have
          terminated.

        * `await' All the threads  started in the scheduler are waiting
          for       a signal.

     An invocation of `scheduler-react!' is called a _reaction_.

 -- Bigloo function: scheduler-start! [ARG [SCHEDULER]]
     Executes `scheduler-react!' as long as the scheduler is not done.
     If the optional argument SCHEDULER is not provided,
     `scheduler-start!' uses the current scheduler (see
     `current-scheduler'). The optional ARG can either be:
        * An integer standing for the number of times `scheduler-react!'
               must be called.

        * A procedure F of one argument. The procedure F       is
          invoked after each reaction. It is passed a value I which is
              the iteration number of the scheduler. The reactions of
          the scheduler       are stopped when F returns `#f'.

          (let* ((s (make-scheduler))
                 (t (make-thread (lambda ()
                                    (let loop ((n 0))
                                       (display n)
                                       (thread-yield!)
                                       (loop (+ 1 n)))))))
             (scheduler-start! 10 s))
            -| 0123456789

          (let* ((s (make-scheduler))
                 (t (make-thread (lambda ()
                                    (let loop ((n 0))
                                       (display n)
                                       (thread-yield!)
                                       (loop (+ 1 n)))))))
             (scheduler-start! (lambda (i) (read-char)) s))
            -| 0123456789

 -- Bigloo function: scheduler-terminate! [SCHEDULER]
     Terminates all the threads in SCHEDULER.

 -- Bigloo function: scheduler-instant [SCHEDULER]
     Returns the current reaction number of SCHEDULER. The reaction
     number is the number of times `scheduler-react!' has been invoked
     passing SCHEDULER as argument.


File: bigloo.info,  Node: Signal,  Prev: Scheduler,  Up: Fair Threads Api

9.2.2.3 Signal
..............

 -- Bigloo function: broadcast! SIGNAL [VAL]
     Broadcasts SIGNAL to all threads started in SCHEDULER
     _immediately_, that is during the reaction. This function can only
     be called from within a running thread. If the optional argument
     VAL is omitted, the SIGNAL is broadcast with an unspecified value.

          (thread-start! (make-thread
          		(lambda ()
          		   (thread-await! 'foo)
          		   (print (scheduler-instant (current-scheduler))))))
          (thread-start! (make-thread
          		(lambda ()
          		   (broadcast! 'foo))))
          (scheduler-start!)
            -| 1

 -- Bigloo function: scheduler-broadcast! SCHEDULER SIGNAL [VAL]
     At the next react broadcasts SIGNAL to all threads started in
     SCHEDULER. This is used to impact running threads from outside any
     threads. If the optional argument VAL is omitted, the SIGNAL is
     broadcast with an unspecified value.

 -- Bigloo function: make-asynchronous-signal PROC
     This function invokes in the background, the procedure PROC.  This
     function takes one parameter which is the signal that is broadcast
     when the invocation returns. When the host operating system
     supports parallel executions, the invocation of PROC is executed in
     parallel with the waiting thread.

     Asynchronous signals can be used to implement non blocking system
     operations, such as input/output. Here is an example that
     illustrates how to implement concurrent programs that behaves
     similarly with Fair Threads and Posix Threads.

          (define-expander read
             (lambda (x e)
                (cond-expand
          	 (fthread
          	  (thread-await!
          	   (make-aynchronous-signal
          	    (lambda (s)
          	       (read ,@(map (lambda (x) (e x e)) (cdr x)))))))
          	 (else
          	  `(read ,@(map (lambda (x) (e x e)) (cdr x)))))))


File: bigloo.info,  Node: SRFI-18,  Prev: Fair Threads Api,  Up: Fair Threads

9.2.3 SRFI-18
-------------

Bigloo implements SRFI-18 (Multithreading support). This SRFI is
available at `http://srfi.schemers.org/srfi-18/srfi-18.html'. One
should keep in mind that since the Bigloo scheduler is cooperative
Bigloo threads must _cooperate_ at some point in order not to block the
execution of other threads. The functions enforcing cooperation are
`thread-yield!', `thread-sleep!', `thread-join!'  and `thread-await!'.
In addition the SRFI-18 `mutex-unlock' function enforce cooperation.

  Thread locking mechanism is common to Fair Threads and Posix Threads
(see *note Thread Common Functions::).

 -- SRFI-18 function: current-time [SCHEDULER]
     Returns the reaction number of SCHEDULER.

 -- SRFI-18 function: time? OBJ
 -- SRFI-18 function: time->seconds OBJ

 -- SRFI-18 function: join-timeout-exception? OBJ
 -- SRFI-18 function: abandoned-mutex-exception? OBJ
 -- SRFI-18 function: terminated-thread-exception? OBJ
 -- SRFI-18 function: uncaught-exception? OBJ
 -- SRFI-18 function: uncaught-exception-reason EXC


File: bigloo.info,  Node: Posix Threads,  Prev: Fair Threads,  Up: Threads

9.3 Posix Threads
=================

This section describes the Posix-Like multi-threading Bigloo library.
As much as possible, the names exported by this library are compatible
with the Fair Threads library (see Section *note Fair Threads::).

* Menu:

* Using Posix Threads::
* Threads API::
* Mutexes API::
* Condition Variables API::


File: bigloo.info,  Node: Using Posix Threads,  Next: Threads API,  Up: Posix Threads

9.3.1 Using Posix Threads
-------------------------

The Bigloo modules initialization model does not permit to create
threads before the main function is started. In other words, it is
unsafe to use the Posix Threads API at the top level of modules. On
some particular applications this might work correctly. On other it
could produce an error message stating the threads cannot be created or
started before the pthread library is initialized.


File: bigloo.info,  Node: Threads API,  Next: Mutexes API,  Prev: Using Posix Threads,  Up: Posix Threads

9.3.2 Threads
-------------

 -- SRFI-18 function: thread? OBJ
     Returns `#t' if OBJ is a thread, otherwise returns `#f'.

 -- SRFI-18 function: current-thread
     Returns the thread currently running.

 -- SRFI-18 function: make-thread THUNK [NAME]
     Returns a new thread which is not started yet. The body of the
     thread is the body of the procedure THUNK. The optional argument
     NAME can be use to identify the thread. It can be any Bigloo value.

          (module example
             (library pthread)
             (main main))

          (define (main argv)
             (make-thread
              (lambda ()
                 (print 1)
                 (thread-yield!)
                 (print 2))
              'my-thread))

 -- SRFI-18 function: thread-start! THREAD
 -- SRFI-18 function: thread-start-joinable! THREAD
     Runs a thread created with `make-thread'.

 -- SRFI-18 function: thread-name THREAD
     Returns the name of the THREAD that has been passed to
     `make-thread'.

 -- SRFI-18 function: thread-specific THREAD
 -- SRFI-18 function: thread-specific-set! THREAD OBJ
     Returns and sets value in the specific field of the THREAD. If no
     value has been set, `thread-specific' returns an unspecified value.

          (let ((t (make-thread (lambda ()
                                   (print (thread-specific (current-thread)))))))
             (thread-specific-set! t 'foo)
             (thread-start! t)) -| foo

 -- Bigloo function: thread-cleanup THREAD
 -- Bigloo function: thread-cleanup-set! THREAD FUN
     Associates a cleanup function to a thread. The cleanup function is
     called with the thread itself. The cleanup function is executed in
     a context where `current-thread' is the thread owning the cleanup
     function.

          (let ((t (make-thread (lambda () 'done) 'foo)))
             (thread-cleanup-set! t (lambda (v) (print (thread-name (current-thread))
          					     ", exit value: " v)))
             (thread-start! t)) -| foo, exit value: done

 -- SRFI-18 function: thread-yield!
     The current thread _cooperates_.

 -- SRFI-18 function: thread-sleep! TIMEOUT
     The current thread _sleeps_ for a certain period. It is suspended
     and the scheduler is free to select a new thread to be resumed. If
     there is only one thread started in the scheduler, the same thread
     will be resumed.  The time of TIMEOUT is used to determine the
     time the thread must sleep.

     Here are the possible types for TIMEOUT.

        * `date': the thread sleeps at least until the date TIMEOUT.

        * `real': the thread sleeps at least TIMEOUT seconds.

        * `fixum', `elong', `llong': the thread sleeps at least TIMEOUT
          milli-seconds.


 -- SRFI-18 function: thread-terminate! THREAD
     Terminates THREAD as soon as possible.

 -- SRFI-18 function: thread-join! THREAD
     The current thread waits until the THREAD terminates. If THREAD
     terminates, `thread-join!' returns the end-result of the THREAD or
     the end-exception if that thread terminates abnormally.

     It is possible to wait for the termination of the a thread if and
     only if it has been started with `thread-start-joinable!'. In
     particular, threads started with `thread-start' cannot be joined.

 -- SRFI-18 function: terminated-thread-exception? OBJ
 -- SRFI-18 function: uncaught-exception? OBJ
 -- SRFI-18 function: uncaught-exception-reason EXC


File: bigloo.info,  Node: Mutexes API,  Next: Condition Variables API,  Prev: Threads API,  Up: Posix Threads

9.3.3 Mutexes
-------------

Bigloo implements SRFI-18 (Multithreading support). This SRFI is
available at `http://srfi.schemers.org/srfi-18/srfi-18.html'.  Thread
locking mechanism is common to Fair Threads and Posix Threads (see
*note Thread Common Functions::).


File: bigloo.info,  Node: Condition Variables API,  Prev: Mutexes API,  Up: Posix Threads

9.3.4 Condition Variables
-------------------------

Posix thread condition variables follows the common thread API (see
*note Thread Common Functions::).

     (module example
       (library pthread)
       (main argv))

     (define (main argv)
        (let ((res #f)
     	 (lock (make-mutex))
     	 (cv (make-condition-variable)))
           (let* ((th1 (thread-start-joinable!
     		   (make-thread
     		    (lambda ()
     		       (mutex-lock! lock)
     		       (condition-variable-wait! lock cv)
     		       (mutex-unlock! lock)
     		       (set! res 23)))))
     	     (th2 (thread-start!
     		   (make-thread
     		    (lambda ()
     		       (mutex-lock! lock)
     		       (condition-variable-signal! cv)
     		       (mutex-unlock! lock))))))
     	 (thread-join! th1))
           res))


File: bigloo.info,  Node: Regular Parsing,  Next: Lalr Parsing,  Prev: Threads,  Up: Top

10 Regular parsing
******************

Programming languages have poor reading libraries since the lexical
information that can be specified is directly tied to the structure of
the language. For example, in C it's hard to read a rational number
because there is no type rational.  Programs have been written to
circumvent this problem: Lex [Lesk75], for example, is one of them.  We
choose to incorporate in Bigloo a set of new functions to assist in
such parsing. The syntax for regular grammar (also known as regular
analyser) of Bigloo 2.0 (the one described in this document) is not
compatible with former Bigloo versions.

* Menu:

* A New Way of Reading::
* The Syntax of The Regular Grammar::
* The Semantics Actions::
* Options and user definitions::
* Examples of Regular Grammar::


File: bigloo.info,  Node: A New Way of Reading,  Next: The Syntax of The Regular Grammar,  Up: Regular Parsing

10.1 A new way of reading
=========================

There is only one way in Bigloo to read text, _regular reading_, which
is done by the new form:

 -- bigloo procedure: read/rp regular-grammar input-port
     The first argument is a regular grammar (also known as regular
     analyser) and the second a Scheme port.  This way of reading is
     almost the same as the Lex's one. The reader tries to match the
     longest input, from the stream pointed to by INPUT-PORT, with one
     of several regular expressions contained in REGULAR-GRAMMAR. If
     many rules match, the reader takes the first one defined in the
     grammar. When the regular rule has been found the corresponding
     Scheme expression is evaluated.

     _remark: _ The traditional `read' Scheme function is implemented
     as:
          (define-inline (read port)
             (read/rp scheme-grammar port))


File: bigloo.info,  Node: The Syntax of The Regular Grammar,  Next: The Semantics Actions,  Prev: A New Way of Reading,  Up: Regular Parsing

10.2 The syntax of the regular grammar
======================================

A regular grammar is built by the means of the form `regular-grammar':

 -- bigloo syntax: regular-grammar (binding ...) rule ...
     The BINDING and RULE are defined by the following grammar:

          <binding>  ==> (<variable> <re>)
                       | <option>
          <option>   ==> <variable>
          <rule>     ==> <define>
                       | (<cre> <s-expression> <s-expression> ...)
                       | (`else' <s-expression> <s-expression> ...)
          <define>   ==> (define <s-expression>)
          <cre>      ==> <re>
                       | (`context' <symbol> <re>)
                       | (`when' <s-expr> <re>)
                       | (`bol' <re>)
                       | (`eol' <re>)
                       | (`bof' <re>)
                       | (`eof' <re>)
          <re>       ==> <variable>
                       | <char>
                       | <string>
                       | (`:' <re> ...)
                       | (`or' <re> ...)
                       | (`*' <re>)
                       | (`+' <re>)
                       | (`?' <re>)
                       | (`=' <integer> <re>)
                       | (`>=' <integer> <re>)
                       | (`**' <integer> <integer> <re>)
                       | (`...' <integer> <re>)
                       | (`uncase' <re>)
                       | (`in' <cset> ...)
                       | (`out' <cset> ...)
                       | (`and' <cset> <cset>)
                       | (`but' <cset> <cset>)
                       | (`posix' <string>)
          <variable> ==> <symbol>
          <cset>     ==> <string>
                       | <char>
                       | (<string>)
                       | (<char> <char>)

     Here is a description of each construction.

    `(context <symbol> <re>)'
          This allows us to _protect_ an expression. A _protected_
          expression matches (or accepts) a word only if the grammar
          has been set to the corresponding context. *Note The
          Semantics Actions::, for more details.

    `(when <s-expr> <re>)'
          This allows us to _protect_ an expression. A _protected_
          expression matches (or accepts) a word only if the evaluation
          of `<s-expr>' is `#t'. For instance,

               (define *g*
                  (let ((armed #f))
                     (regular-grammar ()
               	 ((when (not armed) (: "#!" (+ (or #\/ alpha))))
               	  (set! armed #t)
               	  (print "start [" (the-string) "]")
               	  (ignore))
               	 ((+ (in #\Space #\Tab))
               	  (ignore))
               	 (else
               	  (the-failure)))))

               (define (main argv)
                  (let ((port (open-input-string "#!/bin/sh #!/bin/zsh")))
                     (print (read/rp *g* port))))

    `(bol <re>)'
          Matches `<re>' at the beginning of line.

    `(eol <re>)'
          Matches `<re>' at the end of line.

    `(bof <re>)'
          Matches `<re>' at the beginning of file.

    `(eof <re>)'
          Matches `<re>' at the end of file.

    `<variable>'
          This is the name of a variable bound by a <binding>
          construction. In addition to user defined variables, some
          already exist. These are:

               all    == (out #\Newline)
               lower  == (in ("az"))
               upper  == (in ("AZ"))
               alpha  == (or lower upper)
               digit  == (in ("09"))
               xdigit == (uncase (in ("af09")))
               alnum  == (uncase (in ("az09")))
               punct  == (in ".,;!?")
               blank  == (in #" \t\n")
               space  == #\Space

          It is a error to reference a variable that it is not bound by
          a <binding>.  Defining a variable that already exists is
          acceptable and causes the former variable definition to be
          erased. Here is an example of a grammar that binds two
          variables, one called `ident' and one called `number'. These
          two variables are used within the grammar to match
          identifiers and numbers.

               (regular-grammar ((ident  (: alpha (* alnum)))
                                 (number (+ digit)))
                  (ident  (cons 'ident (the-string)))
                  (number (cons 'number (the-string)))
                  (else   (cons 'else (the-failure))))

    `<char>'
          The regular language described by one unique character. Here
          is an example of a grammar that accepts either the character
          `#\a' or the character `#\b':

               (regular-grammar ()
                  (#\a (cons 'a (the-string)))
                  (#\b (cons 'b (the-string)))
                  (else (cons 'else (the-failure))))

    `<string>'
          This simple form of regular expression denotes the language
          represented by the string. For instance the regular
          expression `"Bigloo"' matches only the string composed of
          `#\B #\i #\g #\l #\o #\o'. The regular expression `".*["'
          matches the string `#\. #\* #\['.

    `(: <re> ...)'
          This form constructs sequence of regular expression. That is
          a form `<re1> <re2> ... <ren>' matches the language
          construction by concatenation of the language described by
          `<re1>', `<re2>', `<ren>'. Thus, `(: "x" all "y")' matches
          all words of three letters, started by character the `#\x'
          and ended with the character `#\y'.

    `(or <re> ...)'
          This construction denotes conditions. The language described
          by `(or re1 re2)' accepts words accepted by either `re1' or
          `re2'.

    `(* <re>)'
          This is the Kleene operator, the language described by `(*
          <re>)' is the language containing, 0 or more occurrences of
          `<re>'. Thus, the language described by `(* "abc")' accepts
          the empty word and any word composed by a repetition of the
          `abc' (`abc', `abcabc', `abcabcabc', ...).

    `(+ <re>)'
          This expression described non empty repetitions. The form `(+
          re)' is equivalent to `(: re (* re))'. Thus, `(+ "abc")'
          matches the words `abc', `abcabc', etc.

    `(? <re>)'
          This expression described one or zero occurrence. Thus, `(?
          "abc")' matches the empty word or the words `abc'.

    `(= <integer> <re>)'
          This expression described a fix number of repetitions. The
          form `(= num re)' is equivalent to `(: re re ... re)'. Thus,
          the expression `(= 3 "abc")' matches the only word
          `abcabcabc'.  In order to avoid code size explosion when
          compiling, `<integer>' must be smaller than an arbitrary
          constant. In the current version that value is `81'.

    `(>= <integer> <re>)'
          The language described by the expression `(>= int re)'
          accepts word that are, at least, `int' repetitions of `re'.
          For instance, `(>= 10 #\a)', accepts words compound of, at
          least, 10 times the character `#\a'. In order to avoid code
          size explosion when compiling, `<integer>' must be smaller
          than an arbitrary constant. In the current version that value
          is `81'.

    `(** <integer> <integer> <re>)'
          The language described by the expression `(** min max re)'
          accepts word that are repetitions of `re'; the number of
          repetition is in the range `min', `max'. For instance, `(**
          10 20 #\a)'.  In order to avoid code size explosion when
          compiling, `<integer>' must be smaller than an arbitrary
          constant. In the current version that value is `81'.

    `(... <integer> <re>)'
          The subexpression `<re>' has to be a sequence of characters.
          Sequences are build by the operator `:' or by string
          literals. The language described by `(... int re)', denotes,
          the first letter of `re', or the two first letters of `re',
          or the three first letters of `re' or the `int' first letters
          of `re'. Thus, `(... 3 "begin")' is equivalent to `(or "b"
          "be" "beg")'.

    `(uncase <re>)'
          The subexpression `<re>' has to be a sequence construction.
          The language described by `(uncase re)' is the same as `re'
          where letters may be upper case or lower case. For instance,
          `(uncase "begin")', accepts the words `"begin"', `"beGin"',
          `"BEGIN"', `"BegiN"', etc.

    `(in <cset> ...)'
          Denotes union of characters. Characters may be described
          individually such as in `(in #\a #\b #\c #\d)'. They may be
          described by strings. The expression `(in "abcd")' is
          equivalent to `(in #\a #\b #\c #\d)'.  Characters may also be
          described using a range notation that is a list of two
          characters. The expression `(in (#\a #\d))' is equivalent to
          `(in #\a #\b #\c #\d)'. The Ranges may be expresses using
          lists of string. The expression `(in ("ad"))' is equivalent
          to `(in #\a #\b #\c #\d)'.

    `(out <cset> ...)'
          The language described by `(out cset ...)' is opposite to the
          one described by `(in cset ...)'. For instance, `(out
          ("azAZ") (#\0 #\9))' accepts all words of one character that
          are neither letters nor digits. One should not that if the
          character numbered zero may be used inside regular grammar,
          the `out' construction never matches it. Thus to write a rule
          that, for instances, matches every character but `#\Newline'
          including the character zero, one should write:

               (or (out #\Newline) #a000)

    `(and <cset> <cset>)'
          The language described by `(and cset1 cset2)' accepts words
          made of characters that are in both `cset1' and `cset2'.

    `(but <cset> <cset>)'
          The language described by `(but cset1 cset2)' accepts words
          made of characters of `cset1' that are not member of `cset2'.

    `(posix <string>)'
          The expression `(posix string)' allows one to use Posix string
          notation for regular expressions. So, for example, the
          following two expressions are equivalent:

               (posix "[az]+|x*|y{3,5}")

               (or (+ (in ("az"))) (* "x") (** 3 5 "y"))


 -- bigloo syntax: string-case string rule ...
     This form dispatches on strings. it opens an input on `string' a
     read into it according to the regular grammar defined by the
     `binding' and `rule'. Example:

          (define (suffix string)
             (string-case string
                ((: (* all) ".")
                 (ignore))
                ((+ (out #\.))
                 (the-string))
                (else
                 "")))


File: bigloo.info,  Node: The Semantics Actions,  Next: Options and user definitions,  Prev: The Syntax of The Regular Grammar,  Up: Regular Parsing

10.3 The semantics actions
==========================

The semantics actions are regular Scheme expressions. These expressions
appear in an environment where some "extra procedures" are defined.
These procedures are:

 -- bigloo rgc procedure: the-port
     Returns the input port currently in used.

 -- bigloo rgc procedure: the-length
     Get the length of the biggest matching string.

 -- bigloo rgc procedure: the-string
     Get a copy of the last matching string. The function `the-string'
     returns a fresh copy of the matching each time it is called. In
     consequence,

          (let ((l1 (the-string)) (l2 (the-string)))
             (eq? l1 l2))
             => #f

 -- bigloo rgc procedure: the-substring start length
     Get a copy of a substring of the last matching string. If the
     LENGTH is negative, it is subtracted to the whole match length.
     Here is an example of a rule extracting a part of a match:

          (regular-grammar ()
             ((: #\" (* (out #\")) #\")
              (the-substring 1 (-fx (the-length) 1))))

     Which can also be written:

          (regular-grammar ()
             ((: #\" (* (out #\")) #\")
              (the-substring 1 -1)))


 -- bigloo rgc procedure: the-character
 -- bigloo rgc procedure: the-byte
     Returns the first character of a match (respectively, the first
     byte).

 -- bigloo rgc procedure: the-byte-ref n
     Returns the N-th bytes of the matching string.

 -- bigloo rgc procedure: the-symbol
 -- bigloo rgc procedure: the-downcase-symbol
 -- bigloo rgc procedure: the-upcase-symbol
 -- bigloo rgc procedure: the-subsymbol start length
     Convert the last matching string into a symbol. The function
     `the-subsymbol' obeys the same rules as `the-substring'.

 -- bigloo rgc procedure: the-keyword
 -- bigloo rgc procedure: the-downcase-keyword
 -- bigloo rgc procedure: the-upcase-keyword
     Convert the last matching string into a keyword.

 -- bigloo rgc procedure: the-fixnum
     The conversion of the last matching string to fixnum.

 -- bigloo rgc procedure: the-flonum
     The conversion of the last matching string to flonum.

 -- bigloo rgc procedure: the-failure
     Returns the first char that the grammar can't match or the end of
     file object.

 -- bigloo rgc procedure: ignore
     Ignore the parsing, keep reading. It's better to use `(ignore)'
     rather than an expression like `(read/rp GRAMMAR PORT)' in
     semantics actions since the `(ignore)' call will be done in a tail
     recursive way. For instance,

          (let ((g (regular-grammar ()
                      (")"
                       '())
                      ("("
                       (let* ((car (ignore))
                              (cdr (ignore)))
                          (cons car cdr)))
                      ((+ (out "()"))
                       (the-string))))
                (p (open-input-string "(foo(bar(gee)))")))
             (read/rp g p))
             => ("foo" ("bar" ("gee")))

 -- bigloo rgc procedure: rgc-context [context]
     If no CONTEXT is provide, this procedure reset the reader context
     state. That is the reader is in no context. With one argument,
     `context' set the reader in the context CONTEXT. For instance,

          (let ((g (regular-grammar ()
                      ((context foo "foo") (print 'foo-bis))
                      ("foo" (rgc-context 'foo) (print 'foo) (ignore))
                      (else 'done)))
                (p (open-input-string "foofoo")))
             (read/rp g p))
             -| foo
                foo-bis

 -- bigloo rgc procedure: the-context
     Returns the value of the current Rgc context.


File: bigloo.info,  Node: Options and user definitions,  Next: Examples of Regular Grammar,  Prev: The Semantics Actions,  Up: Regular Parsing

10.4 Options and user definitions
=================================

Options act as parameters that are transmitted to the parser on the call
to `read/rp'. Local defines are user functions inserted in the produced
parser, at the same level as the pre-defined `ignore' function.

  Here is an example of grammar using both

     (define gram
        (regular-grammar (x y)

           (define (foo s)
     	 (cons* 'foo x s (ignore)))
           (define (bar s)
     	 (cons* 'bar y s (ignore)))

           ((+ #\a) (foo (the-string)))
           ((+ #\b) (bar (the-string)))
           (else '())))

  This grammar uses two options X and Y. Hence when invokes it takes
two additional values such as:

     (with-input-from-string "aabb"
        (lambda ()
           (read/rp gram (current-input-port) 'option-x 'option-y)))
        => (foo option-x aa bar option-y bb)


File: bigloo.info,  Node: Examples of Regular Grammar,  Prev: Options and user definitions,  Up: Regular Parsing

10.5 Examples of regular grammar
================================

The reader who wants to find a real example should read the code of
Bigloo's reader. But here are small examples

10.5.1 Word count
-----------------

The first example presents a grammar that simulates the Unix program
`wc'.
     (let ((*char* 0)
           (*word* 0)
           (*line* 0))
        (regular-grammar ()
           ((+ #\Newline)
            (set! *char* (+ *char* (the-length)))
            (set! *line* (+ *line* (the-length)))
            (ignore))
           ((+ (in #\space #\tab))
            (set! *char* (+ *char* (the-length)))
            (ignore))
           ((+ (out #\newline #\space #\tab))
            (set! *char* (+ *char* (the-length)))
            (set! *word* (+ 1 *word*))
            (ignore))))

10.5.2 Roman numbers
--------------------

The second example presents a grammar that reads Arabic and Roman
number.
     (let ((par-open 0))
        (regular-grammar ((arabic (in ("09")))
                          (roman  (uncase (in "ivxlcdm"))))
           ((+ (in #" \t\n"))
            (ignore))
           ((+ arabic)
            (string->integer (the-string)))
           ((+ roman)
            (roman->arabic (the-string)))
           (#\(
            (let ((open-key par-open))
               (set! par-open (+ 1 par-open))
               (context 'pair)
               (let loop-pair ((walk (ignore)))
                  (cond
                     ((= open-key par-open)
                      '())
                     (else
                      (cons walk (loop-pair (ignore))))))))
           (#\)
            (set! par-open (- par-open 1))
            (if (< par-open 0)
                (begin
                   (set! par-open 0)
                   (ignore))
                #f))
           ((in "+-*\\")
            (string->symbol (the-string)))
           (else
            (let ((char (the-failure)))
               (if (eof-object? char)
                   char
                   (error "grammar-roman" "Illegal char" char))))))


File: bigloo.info,  Node: Lalr Parsing,  Next: Posix Regular Expressions,  Prev: Regular Parsing,  Up: Top

11 Lalr(1) parsing
******************

Regular grammar generators, like Lex, are often coupled with tools,
such as Yacc and Bison, that can generate parsers for more powerful
languages, namely (a subset of) context-free languages. These tools
take as input a description of the language to be recognized and
generate a parser for that language, written in some other language
(for example, Yacc and Bison generate parsers written in C). The user
must always be aware of the generated parser and that is a nuisance.
Bigloo provides such a tool that overcomes this annoyance. It generates
parsers for the class of Lalr(1) grammars in a more opaque way.

* Menu:

* Grammar Definition::
* Precedence and Associativity::
* The Parsing Function::
* The Regular Grammar::
* Debugging Lalr Grammars::
* A Simple Example::

