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

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

  Copyright (C) 1992-99, 2000-02 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: The Semantics Actions,  Next: Examples of Regular Grammar,  Prev: The Syntax of The Regular Parser,  Up: Regular Parsing

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. Here is an
     example of a rule extracting a part of a match

          (regular-grammar ()
             ((: #\" (* (out #\")) #\")
              (the-substring 1 (-fx (the-length) 1))))

 - bigloo rgc procedure: the-character
     Returns the first character of a match.

 - bigloo rgc procedure: the-symbol
     Convert the last matching string into a symbol.

 - bigloo rgc procedure: the-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: Examples of Regular Grammar,  Prev: The Semantics Actions,  Up: Regular Parsing

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

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))))

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: Errors and Assertions,  Prev: Regular Parsing,  Up: Top

Lalr(1) parsing
***************

  Regular parser 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::


File: bigloo.info,  Node: Grammar Definition,  Next: Precedence and Associativity,  Up: Lalr Parsing

Grammar definition
==================

  An lalr(1) grammar is defined by the form:

 - bigloo syntax: lalr-grammar term-def non-term-def...
     TERM-DEF is a list of terminal elements of the grammar.  Terminals
     can grouped together to form precedence groups by including the
     related symbols in a sub-lists of the TERM-DEF list.  Each
     precedence group must start with one of the keywords `left:',
     `right:' or `none:'- this indicates the associativity of the
     terminal symbol.  Here is a sample TERM-DEF which declares eight
     terminals:
          (terminal-1 terminal-2
           (left: terminal-3 terminal-4)
           terminal-5
           (right: terminal-6)
           (none: terminal-7)
           terminal-8)

     In this case, `terminal-3' and `terminal-4' both have the same
     precedence, which is greater than the precedence assigned to
     `terminal-6'. No precedence was assigned to symbols `terminal-1',
     `terminal-2', `terminal-5' or `terminal-8'.

     Each NON-TERM-DEF is a list whose first element is the
     non-terminal being defined, i.e. a symbol. The remaining elements
     are the production rules associated with this non-terminal. Each
     rule is a list whose first element is the rule itself (a list of
     symbols) and the other elements are the semantic actions
     associated with that particular rule.

     For example, consider the following grammar:
          E ==> E1 + ID {E.val := E1.val + ID.val}
                | ID {E.val := ID.val}

     With Bigloo, it would be written:
          (lalr-grammar
            (plus id)
            (e
             ((e plus id)   (+ e id))
             ((id)          id)))

     The semantic value of a symbol in a rule can be accessed by simply
     using the name of the symbol in the semantic action associated with
     the rule. Because a rule can contain multiple occurrences of the
     same symbol, Bigloo provides a way to access these occurrences
     separately. To do so, the name of each occurrence must be suffixed
     by `@'VAR where VAR is the name of a variable that will be bound
     to the semantic value of the occurrence. For example, if the rule
     is

             ifstmt ==> if E then Stmt else Stmt

     then, in Bigloo, it would look like
          (if-stmt
           ((if e then stmt@conseq else stmt@altern)
            (if (eval e)
                (eval conseq)
                (eval altern))))


File: bigloo.info,  Node: Precedence and Associativity,  Next: The Parsing Function,  Prev: Grammar Definition,  Up: Lalr Parsing

Precedence and associativity
============================

  The bigloo lalr(1) parser generator supports operator precedence and
associativity.  The method for specifying the precedence for terminal
symbols is described in *Note Grammar Definition::.  Precedence is
assigned to each non-terminal production from the precedence of the
last terminal symbol appearing in that production.

  Typically, when the parser generator encounters a shift/reduce
conflict, it produces a warning message, then chooses to reduce.  When
a parser generator has precedence and associativity information, it can
make a much more sophisticated decision.

  Let's use this simple calculator grammar as an example:
     (lalr-grammar
      ((left: op-mult op-div)
       (left: op-add op-sub)
       op-lparen op-rparen
       op-semicolon
       number)
     
      (file
        (())
        ((file stmt)))
      (stmt
        ((expr op-semicolon) (print expr)))
      (expr
        ((number) number)
        ((expr@a op-add expr@b) (+ a b))
        ((expr@a op-sub expr@b) (- a b))
        ((expr@a op-mult expr@b) (* a b))
        ((expr@a op-div expr@b) (/ a b))
        ((op-lparen expr op-rparen) expr))))

  Let's start with this input:
     1 + 2 * 3;

  At the point where the parser has read `1 + 2' and the lookahead
symbol is `*', the parser encounters a shift/reduce conflict.  Should
it first reduce by the `(expr op-add expr)' production or shift the `*'
in the hopes of reducing the latter expression first?

  The `(expr op-add expr)' production has gotten its precedence from the
`op-add' terminal symbol.  This is the precedence of the reduce.  The
precedence of the shift comes from the precedence assigned to the
lookahead terminal symbol, which is `op-mult'.  Since `op-mult' has
higher precedence, the parser generator in this state chooses to shift
and does not produce a warning.

  Here's an example which we can use to demonstrate associativity:
     1 + 2 - 3;

  The parser generator encounters a similar shift/reduce conflict this
time, except that when it tries to determine whether to shift or
reduce, it finds that both actions have the same precedence.  In this
case, the parser generator looks at the associativity of the precedence
group containing the `op-add' and `op-sub'.  Since these are declared
to be left-associative, the parser generator chooses to reduce from
this state, effectively calculating the `1 + 2'.  Had these symbols been
right-associative, the parser would have chosen to shift, effectively
calculating `2 - 3' first.  If these symbols had been declared
non-associative with the `none:' keyword, the parser would generate an
error if it ever encountered this state.


File: bigloo.info,  Node: The Parsing Function,  Next: The Regular Grammar,  Prev: Precedence and Associativity,  Up: Lalr Parsing

The parsing function
====================

  Once a grammar has been defined, it can be used to parse some input
using the following function:

 - bigloo procedure: read/lalrp lg rg port [emptyp]
     This function takes three, possibly four, arguments. The first,
     LG, is the Lalr(1) grammar. The second, RG, is the lexical
     analyzer that feeds the grammar with tokens. The third argument,
     PORT, is the port that contains the input to be parsed. The last
     argument, EMPTYP, if provided, should be a function of one
     argument. It is called with each new token read from the port and
     should return `#t' if the token denotes the end of input. The
     result of the call is the value computed by the semantic actions
     of the production rules.


File: bigloo.info,  Node: The Regular Grammar,  Next: Debugging Lalr Grammars,  Prev: The Parsing Function,  Up: Lalr Parsing

The regular grammar
===================

  In order to work properly, the regular parser used with an Lalr(1)
grammar should follow some conventions:

   * If a semantic value is to be associated with the token just
     parsed, the regular parser should return a pair whose `car' is the
     token name (a symbol) and the `cdr' is the semantic value.

   * If there is no value associated with the token, the regular
     grammar can return just the token name. When used in conjunction
     with an Lalr grammar, regular grammar should never return `#f' as
     a token value. This is specially true when the regular grammar
     detects the end of parsing. In that case, the regular grammar
     _must note_ returns the `#f' value. A good way to handle
     end-of-file is illustrated in the following example:

          (let ((g (regular-grammar ()
                       ...
                       (else
                        (let ((c (the-failure)))
                           (if (eof-object? c)
                               c
                               (error 'rgc "Illegal character" c))))))
                (l (lalr-grammar ...)))
             (read/lalrp l g (current-input-port)))

     This way, the Lalr grammar will automatically handles the
     end-of-file.


File: bigloo.info,  Node: Debugging Lalr Grammars,  Next: A Simple Example,  Prev: The Regular Grammar,  Up: Lalr Parsing

Debugging Lalr Grammars
=======================

  Currently the debugging facility for debugging Lalr grammars is very
limited.

 - bigloo variable: *debug-parser*
     When set to true, The variable *DEBUG-PARSER*, outputs all of the
     state changes the parser is going through.


File: bigloo.info,  Node: A Simple Example,  Prev: Debugging Lalr Grammars,  Up: Lalr Parsing

A simple example
================

  Here is the code for a simple calculator implemented by an Lalr(1)
grammar:

     (begin
       (read/lalrp
        (lalr-grammar
         (nl plus mult minus div const lpar rpar)
         (lines
          (())
          ((lines expression nl)    (display "--> ")
                                    (display expression)
                                    (newline))
          ((lines nl)))
         (expression
          ((expression plus term)   (+ expression term))
          ((expression minus term)  (- expression term))
          ((term)                   term))
         (term
          ((term mult factor)       (* term factor))
          ((term div factor)        (/ term factor))
          ((factor)                 factor))
         (factor
          ((lpar expression rpar)   expression)
          ((const)                  const)))
     
        (regular-grammar ()
         ((+ (or #\tab #\space)) (ignore))
         (#\newline              'nl)
         ((+ digit)              (cons 'const (string->number (the-string))))
         (#\+                    'plus)
         (#\-                    'minus)
         (#\*                    'mult)
         (#\/                    'div)
         (#\(                    'lpar)
         (#\)                    'rpar))
     
        (current-input-port))
       (reset-eof (current-input-port)))


File: bigloo.info,  Node: Errors and Assertions,  Next: Eval,  Prev: Lalr Parsing,  Up: Top

Errors and Assertions
*********************

  Bigloo permits to signal an error via the `error' function. Errors
may be trapped with the `try' form. Assertions allow the checking of
predicates at certain points in programs.

 - bigloo procedure: error proc msg obj
     This form signals an error by calling the current error handler
     with PROC, MSG and OBJ as arguments.

          (define (foo l)
             (if (not (pair? l))
                 (error "foo" "argument not a pair" l)
                 (car l)))
          
          (foo 4)
          error--> *** ERROR:bigloo:foo:
                   argument not a pair -- 4

     Switching on the `-g' compilation switch enables stack dumping
     when the `error' function is invoked. That is, when a program is
     compiled with `-g' and when, at runtime, the shell variable
     `BIGLOOSTACKDEPTH' is set and contains a number, an execution
     stack of depth `BIGLOOSTACKDEPTH' is printed when an error is
     raised.

 - bigloo procedure: error/location proc msg obj file location
     This form signals an error by calling the current error handler
     with PROC, MSG and OBJ as arguments. The error is prompted in
     FILE, at character position LOCATION.

          (define (foo l)
             (if (not (pair? l))
                 (error/location
                   "foo" "argument not a pair" l "foo.scm" 115)
                 (car l)))
          
          (foo 4)
          error--> File "foo.scm", line 4, character 115:
                   #       (car l)))
                   #       ^
                   # *** ERROR:bigloo:foo
                   # argument not a pair -- 4
                       0. FOO
                       1. DYNAMIC-WIND
                       2. INTERP
                       3. ENGINE
                       4. MAIN

 - bigloo syntax: try exp handler
     The argument EXP is evaluated. If an error is raised, the HANDLER
     is called. The argument HANDLER is a procedure of four arguments.
     Its first argument is the continuation of TRY. The other arguments
     are PROC, MSG and OBJ. Invoking the first argument will resume
     after the error.

          (let ((handler (lambda (escape proc mes obj)
                            (print "***ERROR:" proc ":" mes " -- " obj)
                            (escape #f))))
             (try (car 1) handler))
             -| ***ERROR:CAR:not a pair -- 1
             => #f

     The argument HANDLER is not evaluated in the dynamic scope of its
     `try' form. That is:

          (let ((handler (lambda (escape proc mes obj)
                            (escape (car obj)))))
             (try (car 1) handler))
             error--> *** ERROR:bigloo:CAR
                      Type `PAIR' expected, `BINT' provided -- 1

  Some library functions exist to help in writing handlers:

 - bigloo procedure: notify-error proc msg obj
     Display on error port PROC, MSG and OBJ.

 - bigloo variable: *warning*
     If this variable is `#t' warning messages are enabled.

 - bigloo procedure: warning [arg]...
     This form signals a warning. That is, is ARG are displayed on the
     standard error port.

          (define (foo l)
             (if (not (pair? l))
                 (begin
                    (warning "foo:" "argument not a pair -- " l)
                    '())
                 (car l)))
          
          (foo 4)
          -| *** WARNING:bigloo:foo:
             argument not a pair -- 4
          => '()

 - bigloo procedure: warning/location file location [arg]...
     This form signals a warning. That is, is ARG are displayed on the
     standard error port. The warning is prompted in FILE at character
     position LOCATION.

          (define (foo l)
             (if (not (pair? l))
                 (begin
                    (warning/location
                      "foo.scm" 154 "foo:" "argument not a pair -- " l)
                    '())
                 (car l)))
          
          (foo 4)
          -| File "foo.scm", line 6, character 154:
             #       (car l)))
             #       ^
             # *** WARNING:bigloo:foo:
             argument not a pair -- 4
          => '()

 - bigloo syntax: assert (var...) s-expression
     Assertions can be enabled or disabled using Bigloo's compilation
     flags `-g' flag to enable them). If the assertions are disabled
     they are not evaluated. If an assertion is evaluated, if the
     expression EXP does not evaluate to `#t', an error is signaled and
     the interpreter is launched in an environment where VAR... are
     bound to their current values.

     Assertion forms are legal expressions which _always_ evaluate to
     the `unspecified' object.

     Here is an example of assertion usage:

          (module foo
             (eval (export foo)))
          
          (define (foo x y)
             [assert (x y) (< x y)]
             (labels ((gee (t)
                           [assert (t) (>= t 0)]
                           (let ((res (+ x t)))
                              [assert (res t) (> res 10)]
                              res)))
                (set! x (gee y))
                [assert (x) (> x 10)]
                x))
          
          (repl)

     This module is compiled with the `-g' flag to enable assertions,
     then the produced executable is run:

          $ a.out
          
          1:=> (foo 1 2)
          
          File "foo.scm", line 9, character 158:
          #                   [assert (res t) (> res 10)]
          #                   ^
          # *** ERROR:bigloo:assert
          # assertion failed -- (BEGIN (> RES 10))
              0. GEE
              1. FOO
          -----------------------
          Variables' value are :
             RES : 3
             T : 2
          -----------------------
          *:=> ^D
          File "foo.scm", line 12, character 228:
          #      [assert (x) (> x 10)]
          #      ^
          # *** ERROR:bigloo:assert
          # assertion failed -- (BEGIN (> X 10))
              0. FOO
          -----------------------
          Variables' value are :
             X : 3
          -----------------------
          
          *:=> 3
          1:=> (foo 1 2)
          File "foo.scm", line 9, character 158:
          #                   [assert (res t) (> res 10)]
          #                   ^
          # *** ERROR:bigloo:assert
          # assertion failed -- (BEGIN (> RES 10))
              0. GEE
              1. FOO
          -----------------------
          Variables' value are :
             RES : 3
             T : 2
          -----------------------
          
          *:=>


File: bigloo.info,  Node: Eval,  Next: Macro Expansion,  Prev: Errors and Assertions,  Up: Top

Eval and code interpretation
****************************

  Bigloo includes an interpreter. Unfortunately, the language accepted
by the interpreter is a proper subset of that accepted by the compiler.
The main differences are:

   * No foreign objects can be handled by interpreter.

   * None of the object system constructions are available from the
      interpreter.

   * The interpreter ignores modules, and has a unique global
     environment.

  Compiled code and interpreted code can be mixed together. That is,
interpreted code is allowed to call compiled code and vice versa. This
connection can be use to circumvent the missing features of the
interpreter (see Section *note Module Declaration::, for a description
of how to connect compiled and interpreted code).

* Menu:

* Eval standard functions::
* Eval command line options::
* Eval and the foreign interface::


File: bigloo.info,  Node: Eval standard functions,  Next: Eval command line options,  Prev: Eval,  Up: Eval

Eval standard functions
=======================

 - procedure: eval exp [env]
     This form evaluates EXP. The second argument is optional. It can be
     the evaluation of one of these three function forms:
          (scheme-report-environment 5)
          (null-environment 5)
          (interaction-environment)

 - procedure: scheme-report-environment version
 - procedure: null-environment VERSION
 - procedure: interaction-environment VERSION
     These three procedures have the definitions given in the R5RS so
     see *Note scheme-report-environment: (r5rs.info)Eval, for more
     details.

 - bigloo procedure: repl
     This invokes the READ-EVAL-PRINT loop. Several `repl' can be
     embedded.

     The `repl' function can be used to implement custom Bigloo
     interpreters.  For instance, one may write:

          (module repl)
          (repl)

     When compiled, this will deliver an executable containing the sole
     Bigloo interpreter.

 - bigloo procedure: quit
     This exits from the currently running `repl'. If the current
     `repl' is the first one then this function ends the interpreter.

 - bigloo procedure: set-prompter! proc
     The argument PROC has to be a procedure of one argument and
     invoking this function sets the `repl' prompter. That is, to
     display its prompt, `repl' invokes PROC giving it the nesting
     level of the current loop as its argument.

 - bigloo procedure: get-prompter
     Returns the current `repl' prompter.

 - bigloo procedure: set-repl-printer! proc
     The argument PROC has to be a procedure accepting one or two
     arguments.  This function sets the `repl' display function. That
     is, to display the result of its evaluations, `repl' invokes PROC
     giving it the evaluated expression as first argument and the
     current output port (or a file in case of transcript) as second
     argument. `Set-repl-printer!' returns the former `repl' display
     function.

     For instance, one may write:

          1:=> (define x (cons 1 2))         -| X
          1:=> (define y (cons x x))         -| Y
          1:=> y                             -| (#0=(1 . 2) . #0#)
          1:=> (set-repl-printer! display)   -| #<procedure:83b8c70.-2>
          1:=> y                             -| ((1 . 2) 1 . 2)

 - bigloo procedure: native-repl-printer
     Returns the native (default) `repl' display function.

 - bigloo procedure: expand exp
     Returns the value of EXP after all macro expansions have been
     performed.

 - bigloo procedure: expand-once exp
     Returns the value of EXP after one macro expansion has been
     performed.

  It is possible to specify files which have to be loaded when the
interpreter is invoked. For this, see section *note Compiler
Description::.

  If a Bigloo file starts with the line:
      #! bigloo-command-name

  and if this file is executable (in the meaning of the system) and if
the user tries to execute it, Bigloo will evaluate it. Note also that
SRFI-22 support enables to run any Unix interpreter (*note SRFIs::).

 - bigloo procedure: load filename
 - bigloo procedure: loadq filename
     FILENAME should be a string naming an existing file which contains
     Bigloo source code. This file is searched in the current directory
     and in all the directories mentioned in the variable `*load-path*'.
     The `load' procedure reads expressions and definitions from the
     file, evaluating them sequentially. If the file loaded is a module
     (i.e. if it begins with a regular module clause), load behaves as
     module initialization. Otherwise, this function returns the result
     of the last evaluation. The function `oadq' differs from the
     function `load' in the sense that `loadq' does not print any
     intermediate evaluations.

     Both functions return the full path of the loaded file.

 - bigloo procedure: loada filename
     Loads an "access file", which allows the interpreter to find the
     modules imported by a loaded module. It returns the full path of
     the loaded file.

 - bigloo variable: *load-path*
     A list of search paths for the `load' functions.

 - bigloo procedure: dynamic-load filename [init-point]
     Load a shared library named `filename'. The function returns the
     name of the loaded library. If INIT-POINT is specified and if it
     is a string and if the library defines a function named
     `init-point', this function is called when the library is loaded.
     INIT-POINT is a C identifier, not a Scheme identifier. In order to
     set the C name a Scheme function, use the extern `export' clause
     (see Section *note C Interface::). If the INIT-POINT value is not
     provided, once the library is loaded, `dynamic-load' uses the
     Bigloo default entry point. Normally you should _not_ provide an
     INIT-POINT to `dynamic-load' unless you known what you are doing.
     When producing C code, to force the Bigloo compiler to emit such a
     default entry point, use the `-dload-sym' compilation option (see
     Section *note Compiler Description::). This option is useless when
     using the JVM code generator. Let's assume a Linux system and two
     Bigloo modules:

          (module mod1
             (eval (export foo))
             (export (foo x)))
          
          (define (foo x)
             (print "foo: " x))
          
          (foo 4)

          (module mod2
             (import (mod1 "mod1.scm"))
             (eval (export bar))
             (export (bar x)))
          
          (define (bar x)
             (print "bar: " x))
          
          (bar 5)

     If these modules are compiled as:

          $ bigloo mod1.scm -c -o mod1.o
          $ bigloo mod2.scm -c -o mod2.o -dload-sym

     Then, if a shared library is built using these two modules:

          $ ld -G -o lib.so mod1.o mod2.o

     Then, `lib.so' cant be dynamically loaded and the variables it
     defines used such as :

          $ bigloo -i
          (dynamic-load "lib.so")
               -| foo: 4
                 bar: 5
          1:=> (foo 6)
               -| foo: 7

     As the example illustrates, when Bigloo modules are dynamically
     loaded, they are initialized. This initialization is ensure _only_
     if `dynamic-load' is called with exactly one parameter. If
     `dynamic-load' is called with two parameters, it is of the
     responsibility of the program to initialize the dynamically loaded
     module before using any Scheme reference.

     _Note: _ In order to let the load module access the variables
     defined by the loader application, special compilation flags must
     be used (e.g., `-rdynamic' under the Linux operating system).
     `Dynamic-load' is implemented on the top of the `dlopen' facility.
     For more information read the `dlopen' and `ld' manuals.


 - bigloo variable: *dynamic-load-path*
     A list of search paths for the `dynamic-load' functions.

 - procedure: transcript-on filename
 - procedure: transcript-off

 - bigloo procedure: default-repl-error-notifier proc obj msg
     This function is the default notifier used to print out error
     message in the `repl'

 - bigloo procedure: set-repl-error-notifier! notifier
 - bigloo procedure: get-repl-error-notifier::procedure
     These procedures set and get the `repl-error-notifier'. The
     argument NOTIFER is a procedure of three arguments.


File: bigloo.info,  Node: Eval command line options,  Next: Eval and the foreign interface,  Prev: Eval standard functions,  Up: Eval

Eval command line options
=========================

  This section presents the Bigloo compiler options that impact the
interaction between compiled and interpreted code. The whole list of
the Bigloo compiler options can be found in *Note The Bigloo command
line: Compiler Description.

   * `-i' Don't compile a module, interprets it!

   * `-export-all' Make all the bindings _defined_ by       the
     compiled module available from the interpreter.

   * `-export-export' Make all the bindings _exported_ by the
     compiled module available from the interpreter.

   * `-export-mutable' Make all the bindings _exported_ by the
     compiled module mutable from outside the module. This option is
       _dangerous_! Either all the modules composing the application
        must be compiled with or without `-export-mutable'. It is
     impossible       to mix `-export-mutable' enabled and disabled
     compilations.


File: bigloo.info,  Node: Eval and the foreign interface,  Prev: Eval command line options,  Up: Eval

Eval and the foreign interface
==============================

  To be able to get access to foreign functions within the Bigloo
interpreter, some extra measurements have to be taken. The foreign
functions have to be present in the interpreter binary, which means you
have to compile a custom interpreter. This is described in Section
*Note Using C bindings within the interpreter::.


File: bigloo.info,  Node: Macro Expansion,  Next: Command Line Parsing,  Prev: Eval,  Up: Top

Macro expansion
***************

  Bigloo make uses of two macro expansion system. The one based on the
expansion passing style [Dybvig et al. 86] and the one advocated by the
R5RS, for which see {No value for `*Note Top: (r5rs.info)Top'}.

Expansion passing style macros
==============================

 - bigloo syntax: define-expander name proc
     This form defines an expander, NAME, where PROC is a procedure of
     two arguments: a form to macro-expand, and an expander.

 - bigloo syntax: define-macro (name [args]...) body
     This form is itself macro-expanded into a `define-expander' form.

     Macro expanders cannot be exported or imported since there is no
     way to specify expanders in a module declaration.

     Macros defined with `define-expander' and `define-macro' are used
     by both the compiler and the interpreter.

  Here is an example of a expander:
     (define-expander when
        (lambda (x e)
           (match-case x
              ((?- ?test . ?exps)
               (e `(if ,test (begin ,@exps)) e))
              (else
                (error "when" "illegal form" x)))))
     
     (when (> a 0) (print a) a)
        ==> (if (> a 0) (begin (print a) a))

  The same example can written with a `define-macro' form:
     (define-macro (when test . exps)
        `(if ,test (begin ,@exps)))

Revised(5) macro expansion
==========================

  Bigloo support the Revised(5) Report on the Scheme programming
language.  For a detailed documentation see *Note r5rs.info:
(R5RS)Expressions.

 - syntax: let-syntax (binding...) body
 - syntax: letrec-syntax (binding...) body
 - syntax: define-syntax keyword transformer
 - syntax: syntax-rules literals rule...
     These three forms are compatible with the description of the
     Revised(5) Report on the Algorithmic Language Scheme.

     Implementation Note: Current Bigloo does not ensure hygiene for
     `let-syntax' and `letrec-syntax'. Hygienic expansion is only
     guaranteed for `define-syntax'.


File: bigloo.info,  Node: Command Line Parsing,  Next: Explicit Typing,  Prev: Macro Expansion,  Up: Top

Command Line Parsing
********************

  Bigloo supports command line argument parsing. That is, when an
application is spawn from an Unix shell, the `main' function  is called
and its argument is bound to the list of the command line arguments,
*Note Module declaration: Modules. The `args-parse' form may be used to
parse these.

 - bigloo syntax: args-parse list rules [null-rule] [else-rule] ...
     The argument LIST is a list of strings. RULES is defined by the
     following grammar:

          <rule>      ==> (`section' <string>)
                        | ((<option> <help>) <s-expression>)
                        | ((<option>) <s-expression>)
                        | ((<flag> <var> <var> ...) <s-expression>)
                        | ((<flag> <var> <var> ... <help>) <s-expression>)
          <null-rule> ==> (`()' <s-expression>)
          <else-rule> ==> (`else' <s-expression>)
          <option>    ==> <flag>
                        | <string><var>
          <flag>      ==> <string>
                        | (<string>+)
          <var>       ==> an identifier leaded by the `?' character
          <help>      ==> (`help' <string>)
                        | (`help' <string> <string>)

     Each elements of LIST are match against the RULES. If one of these
     matches, `args-parse' proceeds as follows:

       1. The matched argument elements of LIST are removed from the
          list.

       2. The `<s-expression>' associated to the matching rule       is
          evaluated in an environment where the rule variables are
          bound.

       3. The argument parsing is resumed with the rest of LIST.

  In addition to parsing the command line arguments, `args-parse'
enables help message printing.

 - bigloo procedure: args-parse-usage fmt
     This is a procedure of one argument, an boolean. `Args-parse-usage'
     constructs an help message from all the option described in a
     `args-parse' form. `Args-parse-usage' is only defined in the
     `<s-expression>' of an `args-parse' form.

  At last, if no rule matches an argument and if the `args-parse' form
contains an `else' rule, this is evaluated. In the `<s-expression>'
part of that rule, a pseudo-variable `else' is bound to the unmatched
argument.

  Here is an example of argument parsing deploying all the possible
rules:

     (module args-example
        (main main))
     
     (define (main argv)
        (args-parse (cdr argv)
           (section "Help")
           (("?")
            (args-parse-usage #f))
           ((("-h" "--help") (help "?,-h,--help" "This help message"))
            (args-parse-usage #f))
           (section "Misc")
           ((("-v" "--version") (help "Version number"))
            (print *version*))
           (("-o" ?file (help "The output file"))
            (set! *dest* file))
           (("--input=?file" (help "The input file"))
            (set! *input* file))
           (else
            (print "Illegal argument `" else "'. Usage:")
            (args-parse-usage #f))))

  Invoking the compiled `args-example' module could produce:

     > bigloo.new args.scm
     args.scm:
     > a.out toto
     Illegal argument `toto'. Usage:
     
     Help:
        ?,-h,--help    --  This help message
     
     Misc:
        -v,--version   --  Version number
        -o <file>      --  The output file
        --input=<file> --  The input file


File: bigloo.info,  Node: Explicit Typing,  Next: C Interface,  Prev: Command Line Parsing,  Up: Top

Explicit typing
***************

  Bigloo supports _type annotation_ or _type information_. As shown in
Section ref Module declaration, these annotations can be written both in
the module clauses and in module bodies although module body type
information is optional. It helps the compiler to produce better quality
code and to reject incorrectly typed programs. Type annotations can
describe both the result and formal parameter types for global
functions and also types for local variable. Due to our module language
design (in particular module initialization), Scheme global variables
_cannot_ support type information.

  _Warning: _ All type annotations are ignore by the interpreter.

  Module body type annotations are introduced by the following special
forms.

 - bigloo syntax: define (f[::type] [a[::type]]...) body
 - bigloo syntax: define-inline (f[::type] [a[::type]]...) body
 - bigloo syntax: let ((var[::type] ...) ...) body
 - bigloo syntax: let loop ((var[::type] ...) ...) body
 - bigloo syntax: let* ((var[::type] ...) ...) body
 - bigloo syntax: letrec ((var[::type] ...) ...) body
 - bigloo syntax: labels ((var[::type] (var[::type]...) b) ...) body
     Type annotations are optional. That is, for any of these
     constructions, if a type annotation is missing, Bigloo uses the
     default generic type `obj' instead.

     Here is an example of type annotated program:

          (module example
             (export (vector-fill!::vector ::vector ::obj)))
          
          (define (vector-fill! v filler)
            (let loop ((i::long (- (vector-length v) 1)))
               (if (= i 0)
                   v
                   (begin
                      (vector-set! v i filler)
                      (loop (- i 1))))))
          
          (let ((v::vector (make-vector 3 4)))
             (vector-fill! v "dummy"))

     The types that can be used in annotations are any of:

        * the basic Scheme types `pair', `null', `bstring', `bint'
          (presented in Section *Note Defining an extern type::).

        * the basic extern types `long', `int', `char', `string'
          presented in Section *Note Defining an extern type::.

        * the compound extern types described in Section *Note Defining
          an extern type::.

        * the types introduced by class declarations (Section *Note
          Class declaration::).

     When a function that contains type annotation is exported, the type
     annotations must be written in the prototype of the function in
     the export clause. In that case the type annotation need to be
     written in the function definition:

          (module foo
             (export (succ::int ::int)))
          
          (define (succ x) (+ 1 x))


File: bigloo.info,  Node: C Interface,  Next: Java Interface,  Prev: Explicit Typing,  Up: Top

The C interface
***************

  We call all the pieces of program devoted to the interactions between
Scheme and another language a _foreign interface_. In Bigloo, the
foreign interface allows Scheme's functions and variables to be
exported to a foreign language and foreign functions and variables to
be imported into the Scheme code. Using the foreign interface requires
two kind of operations.

   * Declarations -- type declarations, import declarations or export
     declarations.

   * Foreign reference in the Scheme code.

  Declarations take place in a special module clause, see *Note Module
Declaration::, and reference to foreign variables within Scheme code
requires no special construction. The current release of Bigloo
includes a C and a Java interface. The Java connection is specified by
the means of a `java' clause (*note Java Interface::).  The C interface
is active (that is the `extern' module clauses are read) only when
compiling to C. So, when compiling to Jvm the binding declared in an
`extern' clause are not bound.

* Menu:

* The syntax of the foreign declarations::
* The very dangerous pragma Bigloo special form::
* Name mangling::
* Embedded Bigloo applications::
* Using C bindings within the interpreter::


File: bigloo.info,  Node: The syntax of the foreign declarations,  Next: The very dangerous pragma Bigloo special form,  Prev: C Interface,  Up: C Interface

The syntax of the foreign declarations
======================================

  The syntax of _foreign_ clauses is defined by:

     <extern> ==> <variable-clause>
          | <function-clause>
          | <include-clause>
          | <export-clause>
          | <type-clause>

  Foreign clauses are automatically "transmitted" by the importation
process.  That is, if module `module1' imports a module `module2',
`module' treats the `extern' clauses of `module2' as though they were
included in its own module declaration. Redefinition of a variable or a
function already defined in an foreign clause is an error.

* Menu:

* Automatic extern clauses generation::
* Importing an extern variable::
* Importing an extern function::
* Including an extern file::
* Exporting a Scheme variable::
* Defining an extern type::


File: bigloo.info,  Node: Automatic extern clauses generation,  Next: Importing an extern variable,  Prev: The syntax of the foreign declarations,  Up: The syntax of the foreign declarations

Automatic extern clauses generation
-----------------------------------

  Extern clauses can be automatically generated using the Cigloo program
which is distributed in the same package as Bigloo. Using Cigloo may be
a good way to understand how C prototypes (and types) have to be
declared in Bigloo. Cigloo reads C files and generates the Bigloo
extern clauses for that files.


File: bigloo.info,  Node: Importing an extern variable,  Next: Importing an extern function,  Prev: Automatic extern clauses generation,  Up: The syntax of the foreign declarations

Importing an extern variable
----------------------------

  The <variable-clause> denotes importation of variables.
     <variable-clause> ==> `(' <typed-ident> <c-name>`)'
          | `(macro' <typed-ident> <string>`)'
          | `(macro' <typed-ident> `('<typed-ident>+`)' <string>`)'

  Only extern "non-`macro'" variables are mutable (that is mutable
using the `set!' construction). Bigloo does not emit "extern C
prototype" for variables introduced by a `macro' clause. <string> is
the C name of variable. The Scheme name of that variable is extracted
from the <typed-ident>.

  Here is an example of variable importations:
     (module example
        (extern (c-var::double "c_var")
                (macro bufsiz::long "BUFSIZ")))
     
     (print "c-var: " c-var)
     (set! c-var (+ 1.0 c-var))
     (print "c-var: " c-var)
     (print "bufsize: " BUFSIZ)


File: bigloo.info,  Node: Importing an extern function,  Next: Including an extern file,  Prev: Importing an extern variable,  Up: The syntax of the foreign declarations

Importing an extern function
----------------------------

  Function are imported using the <function-clause>.

     <function-clause> ==> `('<typed-ident> `('<typed-ident>*`)' <string>`)'
          | `('<typed-ident> `('<typed-ident>+ . <typed-ident>`)' <string>`)'
          | `(macro' <typed-ident> `('<typed-ident>*`)' <string>`)'
          | `(macro' <typed-ident> `('<typed-ident>+ . <typed-ident>`)' <string>`)'

  The function result type and Scheme name are extracted from the
<typed-ident>; the <typed-ident> denotes the type of the function
arguments and <string> is the C name of the function. Bigloo does not
produce "C extern prototype" for macro functions (those introduced by
`macro' clauses). If the typed identifier of the function does not
contain any type information. Bigloo will emit a warning message when
compiling and it will use a default C type (e.g. the `int' C type) as
the return type of the function.

     (module example
        (extern (macro prn::int (::string . ::long) "printf")))
     
     (let ((n (read)))
        (prn #"fib(%d): %d\n" n (fib n)))


File: bigloo.info,  Node: Including an extern file,  Next: Exporting a Scheme variable,  Prev: Importing an extern function,  Up: The syntax of the foreign declarations

Including an extern file
------------------------

  C files can be included in the C code produced by using
<include-clause>.

     <include-clause> ==> `(include' <string>`)'


File: bigloo.info,  Node: Exporting a Scheme variable,  Next: Defining an extern type,  Prev: Including an extern file,  Up: The syntax of the foreign declarations

Exporting a Scheme variable
---------------------------

  A Scheme variable (or function) can be exported to the foreign world
if and only if it is also exported using an `export' clause. Type
information is given in the Scheme exportation, thus, the only
requirement for a variable to be extern exported is to be given a
foreign name. The foreign <export-clause> does this:

     <export-clause> ==> `(export' <ident> <string>`)'

  Here is an example of exportation:

     (module example
        (export (fib::long ::long))
        (extern (export fib "scheme_fib")))
     
     (define (fib x) (if (< x 2) 1 ...))


File: bigloo.info,  Node: Defining an extern type,  Prev: Exporting a Scheme variable,  Up: The syntax of the foreign declarations

Defining an extern type
-----------------------

  New Bigloo types can be defined using extern <type-clause>. These
newly introduced types can be used in any declaration (that is in any
extern _or_ Scheme module clause and in any Scheme variable or function
definition). The syntax of <type-clause> is:

     <type-clause> ==> `(type' <ident> <type-def> <string>`)'
     <type-def> ==> <atomic-type>
          | <ident>
          | <struct-type>
          | <union-type>
          | <function-type>
          | <array-type>
          | <pointer-type>
          | <enum-type>
          | <opaque-type>

  The symbol <ident> is the Scheme name of the introduced type and
<string> is the C name of the type. When Bigloo produces the definition
of a variable v of type s, it produces the following C code: s v`;'.
This rules applies unless s is a pointer or an array and then, to
produce a C definition, the name of the elements of the array or the
elements pointed by the pointer type are used. Hence, if v is for
instance `foo' and s is `(array int)' the produced C code will be: `int
*foo'.

* Menu:

* Atomic types::
* C structures and unions::
* C pointers::
* C null pointers::
* C arrays::
* C functions::
* C enums::
* C opaques::


File: bigloo.info,  Node: Atomic types,  Next: C structures and unions,  Up: Defining an extern type

Atomic types
............

  The atomic types are the pre-existing ones, defined in the standard
Bigloo's library.
     <atomic-type> ==> <bigloo-type>
          | <c-type>
     <bigloo-type> ==> `obj' `procedure'
          | `pair' | `nil' | `pair-nil' | `bint'
          | `blong' | `bbool' | `cnst'
          | `bstring' | `bchar' | `real'
          | `vector' | `tvector' | `struct'
          | `tstruct' | `output-port' | `input-port'
          | `binary-port' | `unspecified' | `symbol'
          | `foreign'
     <c-type> ==> `cobj' `char'
          | `uchar' | `schar' | `short'
          | `ushort' | `int' | `uint' | `long'
          | `ulong' | `slong' | `bool' | `string'
          | `file' | `double' | `float' | `void'
          | `function'

  The type `obj' denotes the super type of all Bigloo types (i.e., all
Bigloo types, such as `procedure', `pair', ...) is an `obj'.  The type
`cobj' denotes the super of all C types (i.e., all preexisting C types
such as `char', `uchar', `schar', `short', ...). The type `pair-nil'
denotes values that are either pairs or the `()' value.

