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: C structures and unions,  Next: C pointers,  Prev: Atomic types,  Up: Defining an extern type

Struct and Union types
......................

  C struct and Union types can be declared in Bigloo using
<struct-type> clauses:

     <struct-type> ==> `(struct' `('<typed-ident> <string>`)^+'`)'
     <union-type> ==> `(union' `('<typed-ident> <string>`)^+'`)'

  This clause declared a C struct but C structure values _cannot_ be
handled by Bigloo. Instead Bigloo is able to handle _pointers to_ C
structure. Thus, in order to help the definition of extern types, when
a struct named STRUCT is defined, if it does not exists yet, Bigloo
automatically defines a type _pointer to the structure_. This type is
named STRUCT`*'.

  When a pointer to a structure type is defined, Bigloo automatically
produces functions to manipulate objects of this type. Let us suppose
the type definition of STRUCT`*':

     (type STRUCT
        (struct (ID1::TYPE1 NAME1)
                ...
                (IDN::TYPEN NAMEN))

  The following functions are created:

   * A creator:
          (STRUCT*::STRUCT* ::TYPE_1 ... ::TYPE_N)

     This function allocates a fresh STRUCT`*' (in the same heap as any
     Scheme value) and fills the fields of the C structure with the
     proper values provided in the call.

   * A type checker:
          (STRUCT*?::bool OBJ::obj)

     This function returns `#t' if and only if the argument OBJ is of
     type STRUCT`*'.

   * A null checker:
          (STRUCT*-null?::bool ::STRUCT*)
     This function returns `#t' if and only if its argument is `Null'.

   * A null creator:
          (make-null-STRUCT::STRUCT*)
     This function creates a `NULL' value of type STRUCT*.

   * An equality checker:
          (=STRUCT*?::bool ::STRUCT* ::STRUCT*)

     This function returns `#t' if and only if its arguments are equal.

   * Accessors and mutators:
          (STRUCT*-ID_1::TYPE_1 ::STRUCT*)
          (STRUCT*-ID_1-set!::obj ::STRUCT* ::TYPE_1)
          ...
     These functions read and store field values.


  Here is an example of structure usage:

     (module foo
        (extern
          (include "named_point_declaration.h")
          (type named-point
                (struct (x::double "x")
                        (y::double "y")
                        (name::string "name"))
                "struct named_point")
          (c-print-point::int (named-point*) "ppoint")))
     
     (define (scheme-print-point point)
        (print "point*-name: " point
               " x: " (named-point*-x point)
               " y: " (named-point*-y point)))
     
     (let ((orig (named-point* 0.0 0.0 "orig")))
        (if (named-point*-null? orig)
            (error "bigloo" "cannot allocate point" orig)
            (begin
               (c-print-point orig)
               (scheme-print-point orig))))


File: bigloo.info,  Node: C pointers,  Next: C null pointers,  Prev: C structures and unions,  Up: Defining an extern type

C pointers
..........

  C pointers are defined by the <pointer-type>

     <pointer-type> ==> `(pointer' <ident>`)'

  <ident> is the name of a previously defined type.  Let us suppose the
pointer type declaration:
     (type PTR (pointer IDENT) ...)

  If IDENT is the name of a structure type, Bigloo creates the
functions presented in paragraph refStruct and Union types.  Otherwise,
it creates the following functions:

   * A creator:
          (make-PTR::PTR NB::long)

     This function allocates memory for NB elements of type IDENT and
     returns a PTR to this zone. The memory is filled with the C `Null'
     value.

   * A type checker:
          (PTR?::bool OBJ::obj)
     This function returns `#t' the argument OBJ is of type PTR and
     `#f' otherwise.

   * A null checker:
          (PTR-null?::bool ::PTR)
     This function returns `#t' if its argument is `Null' and `#f'
     otherwise.

   * A null creator:
          (make-null-PTR::PTR*)
     This function creates a `NULL' value of type PTR*.

   * An equality checker:
          (=PTR*?::bool ::PTR* ::PTR*)
     This function returns `#t' if its arguments are equal and `#f'
     otherwise.

   * Accessors and mutators:
          (PTR-ref::IDENT ::PTR ::long)
          (PTR-set!::obj ::PTR ::long ::IDENT)
     These functions read and store field values.


  Here is an example of a program using pointer types:

     (module foo
        (extern
         (type double* (pointer double) "double *")))
     
     (define (make-vect::double* x y z)
        (let ((vect (make-double* 3)))
           (double*-set! vect 0 x)
           (double*-set! vect 1 y)
           (double*-set! vect 2 z)
           vect))
     
     (define (vect-norm vect::double*)
        (sqrt (+ (expt (double*-ref vect 0) 2)
     	    (expt (double*-ref vect 1) 2)
     	    (expt (double*-ref vect 2) 2))))
     
     (print (vect-norm (make-vect 1.2 4.5 -4.5)))


File: bigloo.info,  Node: C null pointers,  Next: C arrays,  Prev: C pointers,  Up: Defining an extern type

C null pointers
...............

  It may be convenient to build C null pointers. Several means can be
used.  In particular, foreign structures and pointers are provided with
Null creators. For other foreign types, the easiest one is likely to be
a `pragma' form. For instance, in order to create a null pointer to a
`double*' type, one may use:

     (pragma::double* "((double *)0L)")

 - bigloo procedure: string-ptr-null? string
 - bigloo procedure: void*-null? void*
     These two predicates checks if there argument is the C `NULL'
     value.


File: bigloo.info,  Node: C arrays,  Next: C functions,  Prev: C null pointers,  Up: Defining an extern type

C arrays
........

  C arrays are defined by the <array-type>

     <array-type> ==> `(array' <ident>`)'

  <ident> is the name of a previously defined type. Array types are
similar to pointer types except that they include their size in their
type definition string. Let us suppose the array type declaration:
     (type ARRAY (array IDENT) ...)

  If IDENT is the name of a structure type, Bigloo creates the
functions presented in paragraph ref Struct and Union types.
Otherwise, it creates the following functions:

   * A creator:
          (make-ARRAY::ARRAY)
     This function allocates memory for the array ARRAY.  The memory is
     filled with the C `Null' value.

   * A type checker:
          (ARRAY?::bool OBJ::obj)
     This function returns `#t' if the argument OBJ is of type _array_
     and `#f' otherwise.

   * A null checker:
          (null-ARRAY?::bool ::ARRAY)
     This function returns `#t' if the argument OBJ is `Null' and `#f'
     otherwise.

   * An equality checker:
          (=ARRAY*?::bool ::ARRAY* ::ARRAY*)
     This function returns `#t' if its arguments are equal and `#f'
     otherwise.

   * Accessors and mutators:
          (ARRAY-ref::IDENT ::ARRAY ::long)
          (ARRAY-set!::obj ::ARRAY ::long ::IDENT)
     These functions read and store field values.


  Here is an example of a program using array types (`$' in type names
have been presented in Section ref Defining an extern type):

     (module foo
        (extern
         (type double* (array double) "double [ 10 ]")))
     
     (define (make-vect::double* x y z)
        (let ((vect (make-double*)))
           (double*-set! vect 0 x)
           (double*-set! vect 1 y)
           (double*-set! vect 2 z)
           vect))
     
     (define (vect-norm vect::double*)
        (sqrt (+ (expt (double*-ref vect 0) 2)
     	    (expt (double*-ref vect 1) 2)
     	    (expt (double*-ref vect 2) 2))))
     
     
     (print (vect-norm (make-vect 1.2 4.5 -4.5)))


File: bigloo.info,  Node: C functions,  Next: C enums,  Prev: C arrays,  Up: Defining an extern type

C functions
...........

  C function types are introduced by the <function-type> clause:

     <function-type> ==> `(function' <ident> `('<ident>*`))'

  Let us suppose the array type declaration:
     (type FUN (function RES (ARG*)) ...)

  Bigloo creates the following functions:

   * A type checker:
          (FUN?::bool OBJ::obj)
     This function returns `#t' if the argument OBJ is of type FUN and
     `#f' otherwise.

   * An equality checker:
          (=FUN*?::bool ::FUN* ::FUN*)
     This function returns `#t' if and only if its arguments are equal.

   * Caller:
          (FUN-call::RES F::FUN A::TA ...)
     This function invokes F with the arguments A ...  AN.


  Suppose we have to use in Scheme the following C variable:

     double (*convert)(char *);

  It can be done as in:

     (module foo
        (extern
         (type *string->double
               (function double (string))
                         "double (*)(char *)")
         (macro cv::*string->double "convert")))
     
     (print (*string->double-call cv "3.14"))


File: bigloo.info,  Node: C enums,  Next: C opaques,  Prev: C functions,  Up: Defining an extern type

C enums
.......

  This form defines `enum' types.

     <enum-type> ==> `(enum ('<ident> <string>`)...' ...`)'

  Let us suppose the type:
     (type ENUM
        (enum (ID_1 NAME_1)
              ...
              (ID_N NAME_N)))

  Bigloo creates the following functions:

   * Creators:
          (ENUM-ID_1::ENUM)
          ...
          (ENUM-ID_N::ENUM)
     These functions create ENUM values.

   * A type checker:
          (ENUM?::bool OBJ::obj)
     This function returns `#t' if the argument OBJ is of type ENUM and
     `#f' otherwise.

   * An equality checker:
          (=ENUM?::bool ::ENUM ::ENUM)
     This function returns `#t' if the arguments are equal and `#f'
     otherwise.

  Here is an example of Scheme code using ENUM type.

     (module foo
        (extern
         (type gizmo
               (enum (titi "titi")
                     (tutu "tutu")
                     (tata "tata"))
               "enum toto")))
     
     (let ((v1 (gizmo-titi))
           (v2 (gizmo-tutu)))
        (print (=gizmo? v1 v2)))


File: bigloo.info,  Node: C opaques,  Prev: C enums,  Up: Defining an extern type

C opaques
.........

  This form defines `opaque' types.

     <opaque-type> ==> `(opaque)'

  Let us suppose the type:
     (type OPA (opaque) ...)

  Bigloo creates the following functions:
   * A type checker:
          (OPA?::bool OBJ::obj)
     This function returns `#t' if the argument OBJ is of type OPA and
     `#f' otherwise.

   * An equality checker:
          (=OPA?::bool ::OPA ::OPA)
     This function returns `#t' if the arguments are equal and `#f'
     otherwise.

  Opaque types are relevant when a C value must transit via a Scheme
function from a C function to another C function. The value can't be
used in Scheme because no accessors are defined over that type it can
only be send back to a C function.

  Here is an example of Scheme code using OPAQUE type.

     (module foo
        (extern (type filedes (opaque) "FILE *")
                (macro _fopen::filedes (::string ::string) "fopen")
                (_fgetc::int (::filedes) "fgetc")
                (_fclose (::filedes) "fclose"))
        (export (fopen::filedes ::bstring ::bstring)
                (fclose ::filedes)
                (fgetc::char ::filedes)))
     
     (define (fopen fname mode)
        (_fopen fname mode))
     
     (define (fclose filedes)
        (_fclose filedes))
     
     (define (fgetc filedes)
        (integer->char (_fgetc filedes)))

  _Note: _ To illustrate the default type compilation of extern
function, we have voluntary introduced an incomplete declaration for
the `fclose' function. This will make Bigloo to produce a warning when
compiling that module.


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

The very dangerous "pragma" Bigloo special form
===============================================

  Bigloo has a special form which allows the inclusion of C text into
the produced code. It is _only_ applicable to the C back-end.  In
particular, the JVM back-end (see Chapter *Note Java Interface::) does
not support it.

 - bigloo syntax: pragma::IDENT string [args]
     This force Bigloo to include STRING in the produced C code as a
     regular C fragment of code. This form must not be used without an
     in depth understanding of Bigloo C code production; with unskilled
     use, the produced C file may be unacceptable to the C compiler.

     Values can be passed to a `pragma' form, being referenced in
     STRING by expressions of the form `$NUMBER'.  Such expression are
     replaced by the corresponding values, the number of referenced
     values in STRING being exactly the number of values provided. Here
     is an example of `pragma' usage:

          (define (fibo x::long)
             (pragma "printf( \"fib(%d):%d\\n\", $1, $2 );"
                     x
                     (fib x)))

     Arguments provided to a pragma form are not converted during
     compilation.  Hence, pragma arguments can be of any types,
     including, foreign types.

     A pragma result type can be specified using the notation
     `pragma::NAME' where the default type is `unspecified'. Then, for
     instance, the expression `(pragma::bool "$1 == 0" x)' will be
     considered to be returning a object of type `bool' (C boolean)
     while the expression `(pragma "$1 == 0" x)' will be considered by
     Bigloo to be returning the `unspecified' typed object.


File: bigloo.info,  Node: Name mangling,  Next: Embedded Bigloo applications,  Prev: The very dangerous pragma Bigloo special form,  Up: C Interface

Name mangling
=============

  In order to avoid name clashes, Bigloo uses name mangling when
compiling to C or to Jvm. The name mangling for a Scheme identifier may
be overridden by the means of an extern `export' clause (see Section
*Note Exporting a Scheme variable::).

  Four public functions may be used to mangle and to demangle Scheme
identifiers:

 - bigloo procedure: bigloo-mangle string
     Mangle the identifier STRING.

 - bigloo procedure: bigloo-module-mangle string1 string2
     Mangle the identifier STRING1 that belongs to module STRING2.

 - bigloo procedure: bigloo-mangled? string
     Returns `#t' if STRING has been computed by the `bigloo-mangle' or
     `bigloo-module-mangle' function.

 - bigloo procedure: bigloo-class-mangled? string
     Returns `#t' if STRING is a mangled name of a Bigloo class.

 - bigloo procedure: bigloo-need-mangling string
     Returns `#t' if STRING requires name mangling because it is not a
     C or Jvm valid identifier.

 - bigloo procedure: bigloo-demangle string
     Demangle previously mangled identifiers:

          (let ((id "foo!")
                (module "a-module"))
             (let ((mangled (bigloo-module-mangle id module)))
                (multiple-value-bind (new-id new-module)
                   (bigloo-demangle mangled)
                   (and (string=? id new-id) (string=? module new-module)))))
             => #t

 - bigloo procedure: bigloo-class-demangle string
     Demangle previously mangled class identifier.


File: bigloo.info,  Node: Embedded Bigloo applications,  Next: Using C bindings within the interpreter,  Prev: Name mangling,  Up: C Interface

Embedded Bigloo applications
============================

  It is possible to design and realize embedded Bigloo applications.
This facility is useful for adding a new Scheme part to an already
existing C program. The C part of the program has only to enter the
Bigloo initialization, hence, it can call any Bigloo function.

  Normally, Bigloo creates an initialization function called ` main'
when it reads a `main' module clause. To use an embedded Bigloo
program, such an initialization function would have to be created but
with a different name. Changing the name can be be done using the
following Bigloo option: `-copt "-DBIGLOO_MAIN=<NEW-NAME>"'. To prevent
exit from the program after <NEW-NAME> is executed, the following
Bigloo option must be used: `-copt "-DBIGLOO_EXIT='BUNSPEC,'"'.

  A very important part of designing embedded Bigloo programs is being
sure that all used Bigloo modules are correctly initialized and the
normal way to initialize them is to use `with' clauses in the module
which contains the `main' clause.

  An example of an embedded program can be found in the distribution's
examples directory.


File: bigloo.info,  Node: Using C bindings within the interpreter,  Prev: Embedded Bigloo applications,  Up: C Interface

Using C bindings within the interpreter
=======================================

  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. Fortunately, this is easy.  What
has to be done is to wrap the foreign functions within Scheme and make
an interpreter module.

  Let us consider an example where a C function `get_system_time'
returning and `int' is used in an interpreter. (When linking, be sure
to add the `.o' file containing the `get_system_time'.)

  The `ffi-interpreter.scm' file:

     (module ExtendendInterpreter
        (import (wrapper "wrapper.scm"))
        (main main))
     
     (define (main argv)
        (repl))

  The `wrapper.scm' file:

     (module wrapper
        (extern (macro %get-system-time::int () "get_system_time"))
        (export (get-system-time))
        (eval (export-exports))
     
     (define (get-system-time)
       (%get-system-time))

  Compile and link your application with something like:

     cc gettime.c -c gettime.o
     bigloo wrapper.scm -c
     bigloo ffi-interpreter.scm wrapper.o gettime.o


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

The Java interface
******************

  When the Bigloo is configured for a JVM back-end support, the
compiler is able to produce Java class file instead of C files. In
order to produce JVM class files instead of C, use the `-jvm' compiler
option. Example:

     $ cat > foo.scm
     (module foo (main main))
     (define (main argv)
        (print "Hello world: " argv))
     $ bigloo -jvm foo.scm
     $ a.out
       -| Hello world: (/users/serrano/trashcan)

* Menu:

* Compiling with the JVM back-end::
* JVM back-end and SRFI-0::
* Limitation of the JVM back-end::
* Connecting Scheme and Java code::
* Performance of the JVM back-end::


File: bigloo.info,  Node: Compiling with the JVM back-end,  Next: JVM back-end and SRFI-0,  Up: Java Interface

Compiling with the JVM back-end
===============================

Compiler JVM options
--------------------

  All the compiler options that control the compilation (optimization
options, debugging options, etc.), can be use in conjunction of the
`-jvm' option.  However, the `-jvm' option _MUST_ be the first compiler
option on the command line.

  In order to prevent the compiler to produce a JVM `jar' file, it is
required to use simultaneously the `-jvm' and `-c' options.

Compiling multi-modules applications
------------------------------------

  In order to compile and link multi-modules applications, it is require
to specify the association between Scheme source modules and Java
qualified type names. This task is generally complex because of the
annoying mapping that exists from Java class names and the operating
file system names. In order to get rid of this problem, the Bigloo
standard distribution contains a tool, `jfile', that automatically
produces Bigloo Module/Java classes association files. The default name
for such a table is `.jfile'. When compiling a module, Bigloo check if
a `.jfile' exists in the current directory, if it exists, the file is
read. The compilation option `-jfile' may be used to specify an
alternative jfile name. Example:

     $ cat > foo.scm
     (module foo (export (foo))) (define (foo) 'foo)
     $ cat > bar.scm
     (module bar (export (bar))) (define (bar) 'bar)
     $ cat > hux.scm
     (module hux (export (hux))) (define (hux) 'hux)
     $ cat > main.scm
     (module main (main main) (import foo bar hux)
     (define (main argv)
        (print (foo))
        (print (bar))
        (print (fhux)))
     $ afile *.scm > .afile
     $ jfile *.scm > .jfile
     $ bigloo -jvm -c foo.scm
     $ bigloo -jvm -c bar.scm
     $ bigloo -jvm -c hux.scm
     $ bigloo -jvm main.scm foo.class bar.class hux.class

  For an explanation about the `.afile', *note Modules::.


File: bigloo.info,  Node: JVM back-end and SRFI-0,  Next: Limitation of the JVM back-end,  Prev: Compiling with the JVM back-end,  Up: Java Interface

JVM back-end and SRFI-0
=======================

  The currently running back-end may be tested by the means of the
SRFI-0 `cond-expand' form (*note SRFIs::). That is, when the JVM is ran,
the `bigloo-jvm' clause is true. Otherwise, the `bigloo-c' is true.
Example:

     $ cat > foo.scm
     (module foo (main main))
     (define (main argv)
        (cond-expand
           (bigloo-jvm (print "JVM back-end"))
           (bigloo-c (print "C back-end"))
           (else (error "main" "unsupported back-end" #unspecified))))
     $ bigloo -jvm foo.scm
     $ a.out
       -| JVM back-end
     $ bigloo foo.scm
     $ a.out
       -| C back-end


File: bigloo.info,  Node: Limitation of the JVM back-end,  Next: Connecting Scheme and Java code,  Prev: JVM back-end and SRFI-0,  Up: Java Interface

Limitation of the JVM back-end
==============================

  The JVM back-end supports the entire Bigloo source language but the
`call/cc' function. More precisely, using the JVM back-end, the
continuation reified in a `call/cc' form can only be invoked in the
dynamic extent of that form.

  The other restrictions of the C back-end apply to the JVM back-end.
Mainly,

   * Bigloo is not able to compile all the tail recursive call without
     stack consumption (however, most of the tail recursive calls are
     optimized by Bigloo and don't use stack activation frames).

   * Bigloo compiled applications do not check for arithmetic overflow.

   * When compiling to Jvm, the `extern' module clauses are not used.

   * Jvm runtime system does support the following function `chdir'.

   * Jvm runtime system support for `chmod' is restricted.

   * In order to read a shell variable from a Bigloo compiled Jvm
     program,       you have to use the Bigloo link option `-jvm-env'
     _when_       linking that program. However, some shell variables
     are       automatically defined (`HOME', `USER', `CLASSPATH' and
        `TMPDIR'.

   * JVM code generation does not support `pragma' forms.



File: bigloo.info,  Node: Connecting Scheme and Java code,  Next: Performance of the JVM back-end,  Prev: Limitation of the JVM back-end,  Up: Java Interface

Connecting Scheme and Java code
===============================

  When compiling and linking with the JVM back-end, Bigloo source code
may use Java API. That is, Bigloo Scheme source code may use (refer or
set) Java static variables, Bigloo source code may call static or
virtual Java methods. In addition, Bigloo variables and functions may
be exported to Java, that is use, set or called in Java source code.
Java module clause are enabled (read and parsed) only when compiling to
JVM byte code.

  Java definitions are declared in Bigloo module by the mean of a Bigloo
module clause: the _java_ module clause. The syntax of a _Java_ clause
is defined by:

     <java> ==> <declare-class-clause>
          | <declare-abstract-class-clause>
          | <extend-class-clause>
          | <array-clause>
          | <export-clause>

  As for _extern_ clause, _java_ clauses are automatically
"transmitted" by the importation process.  That is, if module `module1'
imports a module `module2', `module' treats the `java' clauses of
`module2' as though they were included in its own module declaration.
Redefinition of a variable or a function already defined in an java
clause is an error. However, the definition of a Java class or an Java
abstract class may be enriched from module to module.

* Menu:

* Automatic Java clauses generation::
* Declaring Java classes::
* Declaring abstract Java classes::
* Extending Java classes::
* Declaring Java arrays::
* Exporting Scheme variables::
* Bigloo runtime customization::


File: bigloo.info,  Node: Automatic Java clauses generation,  Next: Declaring Java classes,  Prev: Connecting Scheme and Java code,  Up: Connecting Scheme and Java code

Automatic Java clauses generation
---------------------------------

  Java clauses can be automatically generated using the Jigloo program
which is distributed in the same package as Bigloo. Using Jigloo may be
a good way to understand how Java API have to be declared in Bigloo.
Jigloo reads Java _class_ files and generate the Bigloo java clauses
for that classes.


File: bigloo.info,  Node: Declaring Java classes,  Next: Declaring abstract Java classes,  Prev: Automatic Java clauses generation,  Up: Connecting Scheme and Java code

Declaring Java classes
----------------------

  The <declare-class-clause> clause denotes importation of Java classes.

     <declare-class-clause> ==> `('class <typed-ident> <slot>* <string>`)'
     <slot> ==> <field> | <method> | <constructor>
     <field> ==> `(field' <modifier> <typed-ident> <string>`)'
     <method> ==> `(field' <modifier> <typed-ident> `('<typed-ident>*`)' <string>`)'
     <constructor> ==> `(constructor' <ident> `('<typed-ident>*`))'
     <modifier> ==> `public' | `private' | `protected'
          | `static' | `final' | `synchronized' | `abstract'

  When the compiler encounters a Java class declaration, it
automatically creates a predicate. If the class identifier is `id', the
predicate is named `id?'. In addition, the compiler generates functions
that fetch and set the field values. For a field named `f', these
functions are named `id-f' and `id-f-set!'. Methods and constructors are
also always prefixed the name of the class. That is, for a method named
`m' of a class `k', the Scheme name of the method is `k-m'.

  Example:

     (module java-example
        (java (class point
                 (constructor new-default ())
                 (field x::int "x")
                 (method show::void (::point) "show")
                 (method static statistics::int () "PointStatistics")
                 "Point")
              (class point-3d::point
                 "Point3D")))
     
     (let ((p (point-new-default)))
        (print (point? p))   -| `#t'
        (point-x-set! p 3)
        (print (point-x p))) -| `3'


File: bigloo.info,  Node: Declaring abstract Java classes,  Next: Extending Java classes,  Prev: Declaring Java classes,  Up: Connecting Scheme and Java code

Declaring abstract Java classes
-------------------------------

  A Bigloo abstract Java class declaration corresponds to a Java
interface.  It cannot be instantiate but regular classes may inherit
from it.

     <declare-abstract-class-clause> ==> `('abstract-class <typed-ident> <slot>* <string>`)'


File: bigloo.info,  Node: Extending Java classes,  Next: Declaring Java arrays,  Prev: Declaring abstract Java classes,  Up: Connecting Scheme and Java code

Extending Java classes
----------------------

  A class definition may be split into several pieces. One class
declaration (see <declare-class-clause>) and several extensions. The
syntax for a Java class extension is:

     <extend-class-clause> ==> `('class <typed-ident> <slot>*`)'

  Example:

     (module java-example2
        (import java-example)
        (java (class point
                 (field y::int "y")
                 (field static num::int "point_num")
                 (constructor new (::int ::int)))))


File: bigloo.info,  Node: Declaring Java arrays,  Next: Exporting Scheme variables,  Prev: Extending Java classes,  Up: Connecting Scheme and Java code

Declaring Java arrays
---------------------

  Java arrays may be allocated and used inside Scheme code. The syntax
of a Java array module clause is:

     <array-clause> ==> `(array' <ident> <typed-ident>`)'

  The <typed-ident> must refer to the name of an existing type (i.e., a
primitive Bigloo type, a Bigloo class, an already defined Java class or
an already defined Java array). For an array named `ar', Bigloo
generates:

   * a creator named `make-ar' which is a function of one integer
     argument.

   * a predicate named `ar?'.

   * a getter named `ar-ref' which is a function of one integer
     argument.

   * a setter named `ar-set!' which is a function of two arguments, an
         integer and a value of the array item types.


  Example:

     (module foo
        (java (array int* ::int)
              (class bar
                 (method static hello::int (::int*) "hello")
                 "bar"))
        (main main))
     
     (define (main argv)
        (let ((tab (make-int* 2)))
           (int*-set! tab 0 3)
           (int*-set! tab 1 6)
           (print (bar-hello tab))))


File: bigloo.info,  Node: Exporting Scheme variables,  Next: Bigloo runtime customization,  Prev: Declaring Java arrays,  Up: Connecting Scheme and Java code

Exporting Scheme variables
--------------------------

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

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

  Here is an example of exportation:

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


File: bigloo.info,  Node: Bigloo runtime customization,  Prev: Exporting Scheme variables,  Up: Connecting Scheme and Java code

Bigloo runtime customization
----------------------------

  When the Scheme program completes normally, that is when the last
expression of the Bigloo main is executed without error, the Bigloo
runtime system explicitly call the Java function `System.exit'. In some
situation, it may be useful to disable this call. For this, one must
set the `boolean' Java static variable `bigloo.foreign.must_exitp' to
`false'. This can be implemented in Java or in Scheme. Here is a Scheme
module that sets the variable to `false'.

     (module no-exit
       (java (class bigloo
                (field static must-exitp::bool "must_exitp")
                "bigloo.foreign")))
     
     (cond-expand
       (bigloo-jvm (set! bigloo-must-exitp #f)))


File: bigloo.info,  Node: Performance of the JVM back-end,  Prev: Connecting Scheme and Java code,  Up: Java Interface

Performance of the JVM back-end
===============================

  We are currently improving and investigating about the performance of
the JVM back-end. JVM performance is extremely sensitive to the host
platform (for instance, very unfortunately, Linux seems to be a poor
platform to run JVM code). Currently, it seems that the JVM back-end
produces codes that are in between 4 times and 10 times slower than
codes produced by the C back-end. The ratio between JVM and C is subject
to changes. The gap between JVM and C code is bound to bridge because
of the huge amount of efforts applied to efficiently implement Java
virtual machines.


File: bigloo.info,  Node: Bigloo Libraries,  Next: Extending the Runtime System,  Prev: SRFIs,  Up: Top

Bigloo Libraries
****************

  Bigloo libraries are collections of global bindings (global variables
and global functions). Bigloo libraries are build on the top of the host
operating system (e.g. Unix) libraries. Because Bigloo uses modules, a
library is not only a bundle of compiled codes and memory locations. A
Bigloo library is splited into several files:

   * one _heap_ that describes the locations of the library.

   * several host library files.

   * possibly, C header files.

   * possibly, a compiler initialization file.

  Let's consider, for example, a library that implements the `format'
Common Lisp facility. Let's suppose we name this library `bformat'.
Using a Unix machine, the Bigloo library will consist of the following
files:

   * `bformat.heap': the heap file.

   * `libbformat.a', `libbformat.so', `libbformat_u.a',
     `libbformat_u.so': the Unix library files. The file names with a
     `_u' are libraries compiled in _unsafe_ and _optimized_ mode.

   * `bformat.h': an include file.

Compiling and linking with a library
====================================

  From the user stand point, using a library can be made two ways:

   * Using the Bigloo `-library LIB-NAME' option where LIB-NAME is the
     name of the Bigloo library (not the name of one of the Unix files
     implementing the library). The name of the library must be _lower
     case_. For instance:

          $ bigloo foo.scm -library bformat

   * Using the module clause `library'. This second solution prevent
     from using a special compilation option. For instance, this module
     will automatically compile and link with the `bformat' library:

          (module foo
             (library bformat))
          
          ...
          (format ...)

  When a Bigloo library `lib' is used, Bigloo automatically searches if
a file called `lib.init' exists. If such a file exits, it is loaded at
compile-time. That file may specifies compilation flags.

  When a Bigloo library `lib' is used, the Bigloo linker automatically
searches for a library to be linked against the application. The name
of the file containing the library depends on the operating system and
the back-end used. For instance, under Unix, for a library called
_NAME_, the Bigloo linker searches for a file called `lib_NAME_.a' or
`lib_NAME_.so' in the compilation linker path when using the native
back-end. It searches for a file `_NAME_.zip' when the JVM back-end is
used.

Library and SRFI
================

  Libraries are related to Scheme SRFIs. That is, when a library is used
the SRFI implemented by the library is registered. Registered SRFIs may
be tested by the `cond-expand' form (*note SRFIs::).

Library and inline functions
============================

  It is illegal for libraries to include inline functions that make use
of new foreign types. By new foreign type, we mean foreign types that
are defined inside the library. A library may contains inline functions
but that inline functions must not even call function using foreign
types in their prototypes. Including inline functions making use of
foreign C type will make the compiler to fail when compiling user code.
The compiler will fail prompting type errors. A library may contains
non-inline functions that make use of new foreign types.

library and repl
================

  It is possible to implement a "read-eval-print-loop" that is extended
with the facilities implemented inside a library. Because of the Bigloo
module initialization process a module that implements an extended
"repl" must reference a least one of the binding of the library. For
instance, here is a module that implements a "repl" with the `format'
facility available:

     (module format-repl
        (library format))
     
     ;; a dummy reference to a facility of the format library
     (let ((dummy format))
        (repl)

Building a library
==================

  Bigloo libraries require several steps before being completed.

   * The first step is to build a _library heap_. This is achieved
     using a special compilation mode: `-mkaddheap -mkaddlib -addheap'.
     That is, for your library you have to create a heap associated
     source file  that imports all the binding you want in your
     library. The heap source file  must be _excluded_ from the source
     files that will be used to build  the host library.

     Suppose we have a unique source file for the `bformat' library.
     The module clause of this source file is:

          (module __format
             (export (format . args)
                     format:version
                     ...
             (eval   (export format)
                     (export format:version)
                     ...

     Prior to compiling the library, we have to create the heap
     associated file (let's name it `make-lib.scm'). This file could be:

          (module __make-lib
             (import (__format "format.scm")))

     Building it is simple:

          bigloo -unsafe -q -mkaddheap -mkaddlib \
               make-lib.scm -addheap format.heap

     The option `-mkaddheap' and `-mkaddlib' tell Bigloo that it is
     compiling an heap associated file. The option `-addheap' tells
     Bigloo the name of the heap file to be produced.

   * The second step is to compile all the library source file. These
     compilation must be done using the `-mkaddlib' compilation mode.
     For example:

          bigloo -O3 -unsafe -mkaddlib              \
             -cc gcc -fsharing -q -rm               \
             -unsafev bformat.scm -o bformat_u.o -c
          bigloo -O3 -mkaddlib -g -cg -cc gcc       \
             -fsharing -q -rm                       \
             -unsafev bformat.scm -o bformat.o -c

     The first compilation produces the _unsafe_ version the second the
     produced the _debugging_ version.

   * The third step is to build the host operating system libraries.
     There is no portable way to do this. This operation may looks like:

          ar qcv libformat.a format.o
          ranlib libformat.a
          ld -G -o libformat.so format.o -lm -lc
          ar qcv libformat_u.a format_u.o
          ranlib libformat_u.a
          ld -G -o libformat_u.so format_u.o -lm -lc

  At this time, you are ready to use your library. The Bigloo
distribution contains library exemplar. Considering these examples as a
departure point for new libraries is probably a good idea.

A complete library example
==========================

  For the means of an example let's suppose we want to design a Bigloo
library for 2d points. That library is made of three implementation
files: two C files, `point.h' and `point.c' and one Scheme file
`scm-point.scm'. Here are defined the three files:

`point.h':
     struct point_2d {
        double x, y;
     };

`point.c':
     #include <stdio.h>
     #include "point.h"
     
     int print_point_2d( struct point_2d *pt ) {
        printf( "<point-2d: %g, %g>", pt->x, pt->y );
     }

`scm-point.scm':
     (module point
        (include "point.sch")
        (extern  (include "point.h"))
        (export  (make-point::s-point_2d* ::double ::double)
                 (print-point             ::s-point_2d*)
                 (point?                  ::obj))
        (eval    (export-all)))
     
     (define (make-point::s-point_2d* x::double y::double)
        (s-point_2d* x y))
     
     (define (print-point p::s-point_2d*)
        (print_point_2d p))
     
     (define (point? obj::obj)
        (s-point_2d*? obj)
        obj)

  We want our library to be composed of the whole exported Scheme
functions. Thus the file to build the heap library could look like:

     (module __make-point-lib
        (import (point "scm-point.scm")))

  Let's suppose that the `point' library requires the `libposix'
library. This means that any file linked with the `point' library needs
to be also linked with the `posix' library. Furthermore, programs
making use of the `point' library needs to include the `point.sch'
file. That Scheme file needs in turn the C file `point.h' otherwise the
produced C files won't compile. The need for the `libposix' library and
for the `point.h' file may be specified inside the `point.init' file.
For our current library, the `point.init' file could look like:

     (set! *ld-options*
           (string-append "-L/usr/lib " *ld-options*))
     
     (set! *bigloo-user-lib*
           (cons "-lposix" *bigloo-user-lib*))
     
     (set! *additional-include-foreign*
           (cons "point.h" *additional-include-foreign*))
     
     (define-macro (point x y)
        `(make-point ,x ,y))

  This file updates some compilation variables (`*ld-options*',
`*bigloo-user-lib*', `*additional-include-foreign*') and defines a
macro: `point'. Because the `point.init' file will be loaded each time
a compilation require the `point' library is spawned, user code are
allowed to use the `point' macro. Here is an example file making use of
the `point' library:

     (module example
        (include "point.sch"))
     
     (let ((p (point 2.9 3.5)))
        (print "point?: " (point? p))
        (print "point?: " (point? 4))
        (print-point p)
        (print (eval `(point? ,p)))
        (eval `(print-point ,p))
        (print "done..."))

  To conclude that example here is the `Makefile' used to compile the
`point' library, heap file and one example.

     # bigloo flags
     BIGLOO          = bigloo
     BHEAPFLAGS      = -unsafe -q -mkaddheap -mkaddlib -v2
     BCOMMONFLAGGS   = -mkaddlib -fsharing -q $(VERBOSE)        \
                       -copt '$(CCOMMONFLAGS)' -cc $(CC)
     BSAFEFLAGS      = $(BCOMMONFLAGGS) -cg -O3 -g -cg -unsafev \
                       -eval '(set! *indent* 4)' -rm
     BUNSAFEFLAGS    = $(BCOMMONFLAGS) -O4 -unsafe
     
     # cigloo flags
     CIGLOO          = cigloo
     
     # cflags
     CC              = gcc
     CCOMMONFLAGS    = -I.
     CSAFEFLAGS      = $(CCOMMONFLAGS)
     CUNSAFEFLAGS    = $(CCOMMONFLAGS) -O2
     
     # library objects
     SAFE_OBJECT     = olib/scm-point.o olib/point.o
     UNSAFE_OBJECT   = olib_u/scm-point.o olib_u/point.o
     
     all: heap lib example
     
     heap: point.heap
     
     point.heap: point.sch scm-point.scm
             $(BIGLOO) $(BHEAPFLAGS) make-lib.scm -addheap point.heap
     
     lib: lib_u lib.a
     
     lib.a: olib $(SAFE_OBJECT)
             ar qcv libpoint.a $(SAFE_OBJECT)
     
     lib_u: olib_u $(UNSAFE_OBJECT)
             ar qcv libpoint_u.a $(UNSAFE_OBJECT)
     
     olib:
             mkdir olib
     
     olib_u:
             mkdir olib_u
     
     olib_u/scm-point.o olib/scm-point.o: scm-point.scm
             $(BIGLOO) $(BSAFEFLAGS) $(<F) -o $*.o -c
     
     olib_u/point.o olib/point.o: point.c
             $(CC) $(CSAFEFLAGS) $(<F) -o $*.o -c
     
     point.sch: point.h point.c
             cigloo $^ > point.sch
     
     example: heap lib
             $(BIGLOO) -v2 -L . -library point \
                 -static-bigloo example.scm -o example
     
     clean:
             -/bin/rm -f point.heap
             -/bin/rm -f point.sch scm-point.c
             -/bin/rm -fr olib olib_u
             -/bin/rm -f example example.c example.o
             -/bin/rm -f libpoint.a libpoint_u.a

Library and modules
===================

  A Bigloo library may be composed of several Bigloo modules (even if in
our example only one module was used). The modules composing the library
are free to import each other. Nevertheless, someone designing a Bigloo
library should be aware that Bigloo importation creates dependences
between modules. A module `mod1' that imports a module `mod2' depends
on `mod2' because `mod1' requires `mod2' to be initialized (i.e. `mod1'
calls to the initialization function of `mod2'). The result is that
using `import' clauses inside modules composing a library may create a
lot of dependencies between the object files that are used to build the
associated Unix library. Dependencies should be avoided because they
make the Unix linkers unable to produce small stand-alone programs.
Instead of `import' clauses, `use' clauses should be preferred. `Use'
clauses do not create dependencies because a module `mod1' that `use's
a second module `mod2' does not require `mod2' to be initialized. Of
course, it may happen situations where the initialization is mandatory
and thus, the `import' must not be replaced with a `use' clause. The
source code of the Bigloo library makes use of `import' and `use'
clauses. The Bigloo standard library should be studied as an example.


File: bigloo.info,  Node: Extending the Runtime System,  Next: DSSSL Support,  Prev: Bigloo Libraries,  Up: Top

Extending the Runtime System
****************************

  _Custom Types_ types are not documented yet. This facility enables
extension to the standard Bigloo runtime system. The current
implementation of custom types is subject to change. It will be
documented in coming releases.

