This is sizzle-embed.info, produced by makeinfo version 4.0 from
sizzle-embed.texi.

INFO-DIR-SECTION Sizzle Scheme Interpreter
START-INFO-DIR-ENTRY
* sizzle-embed: (sizzle-embed).     Embedding Sizzle
END-INFO-DIR-ENTRY

   This file documents embedding of the Sizzle Scheme interpreter.

   Copyright (C) 1999, 2000 Martin Grabmueller

   Permission is granted to make and distribute verbatim copies of this
manual provided the copyright notice and this permission notice are
preserved on all copies.


File: sizzle-embed.info,  Node: sizzle-gen-if,  Next: Index,  Prev: Adding Primitives,  Up: Top

sizzle-gen-if
*************

   Included in the Sizzle distribution is the script `sizzle-gen-if'.
This script can be used to automatically generate glue code for C
functions from an interface specification.  It is possible (in some
simple cases) to generate a primitive function for wrapping a C library
function without writing a single line of code.  An example for this is
the procedure `fnmatch', which was included into the Sizzle core by
specifying its interface, and the rest (primitive procedure code,
parameter checking, parameter unboxing, return value boxing, primitive
definition, constant definition) was handled by `sizzle-gen-if'.

   This section documents the use of the script.  For further
information, you can of course always refer to the source code and the
file `fnmatch.if' in the directory `libsizzle' of the distribution,
which demonstrates the use.

* Menu:

* sizzle-gen-if invocation::    How sizzle-gen-if must be called
* The Generation Process::      What does sizzle-gen-if?
* The Specification File::      How to specify interfaces
* A Simple Example strlen::     Example interface and output
* Manual Glue Code::            Write the glue code by hand
* Pointer arguments::           How sizzle-gen-if can handle pointers


File: sizzle-embed.info,  Node: sizzle-gen-if invocation,  Next: The Generation Process,  Prev: sizzle-gen-if,  Up: sizzle-gen-if

sizzle-gen-if invocation
========================

   `sizzle-gen-if' is used as follows.
     $ sizzle-gen-if infile outfile

   The script must be invoked with the input file as the first and the
primary output file as the second argument.  It will copy the input file
to the output file and replace interface specification marked with a
`$' character with the corresponfing generated glue code.
Additionally, a "init file" will be created, with the name of the
output file with and `.x' appended.  This file will contain the
necessary initialization code for registering primitives, creating
constants and symbols and protecting global variables from garbage
collection.  The output file can then be `#include''d into any C source
file, and the init file should be `#include''d into the init function
of that source file, so that initialization can take place for the
generated wrapper code.

   Suppose you have an interface specification file called
`fnmatch.if', which specifies how the C function `fnmatch' must be
called, and which possibly defines some constants or symbols.  To
generate the glue code and the initialization statements, you have to
call `sizzle-gen-if' with the name of the file and the name the output
file should have.
     mgrabmue@tortoise (~/cvs/sizzle/scripts): sizzle-gen-if fnmatch.if fnmatch.c
     mgrabmue@tortoise (~/cvs/sizzle/scripts):
   When no errors are found, `sizzle-gen-if' does not print any
messages.  You can have a look at the current directory to see which
files have been created.
     mgrabmue@tortoise (~/cvs/sizzle/scripts): ls -l fnmatch.*
     -rw-r--r--   1 mgrabmue mgrabmue     3263 Aug 22 15:26 fnmatch.c
     -rw-r--r--   1 mgrabmue mgrabmue      568 Aug 22 15:26 fnmatch.c.x
     -rw-r--r--   1 mgrabmue mgrabmue      658 Aug 22 12:26 fnmatch.if
     mgrabmue@tortoise (~/cvs/sizzle/scripts):
   As you can see, the output file `fnmatch.c' exists now, and it is
considerably bigger than the input file.  This can give you a feeling
how much typing you have saved by using `sizzle-gen-if' :-)

   Additionally, the initialization file `fnmatch.c.x' was created.  It
holds the code needed to register the newly generated primitive
procedure, so that is gets accessible to the outer world.


File: sizzle-embed.info,  Node: The Generation Process,  Next: The Specification File,  Prev: sizzle-gen-if invocation,  Up: sizzle-gen-if

The Generation Process.
=======================

   An interface specification file is processed by `sizzle-gen-if'
under the following rules:

   * All data is copied verbatim to the output file, except when
     escaped with the escape character `$', which indicates the
     beginning of an interface specification.

   * The escape character is `$'.  After this character, a Scheme
     object is read using the standard procedure `read' and processed as
     an interface specification.  All whitespace following the
     specification will be discarded.  The result of applying the
     interface specification will then be written to the output file.

   * Additionally, data may be written to the initialization file as
     needed.  This can be code for registering primitives, protecting
     global variables from garbage collection and creation of symbols
     and constant values.


File: sizzle-embed.info,  Node: The Specification File,  Next: A Simple Example strlen,  Prev: The Generation Process,  Up: sizzle-gen-if

The Specification File
======================

   A specification file can contain arbitrary text.  The use of
interface specifications must be explicitly announced with the character
`$'. All other data is simply copied to the output file.  This is
useful to include things like preprocessor statements, other variable
declarations or even helper functions in the interface file.

   When a `$' character is read, a Scheme expression representing an
interface specification is expected.  After reading this expression
(which will discard any whitespace after the expression), character
copying starts again, until a `$' is read, and so on.

   This is the grammar for an interface specification.
     <if-spec>        ::= <func-spec> | <cpp-const-spec> |
                          <symbol-spec> | <exception-spec>
     <func-spec>      ::= "(" "function" <ret-type> <func-name>
                          "(" <param-list> ")" [glue-code] ")"
     <func-name>      ::= identifier
     <ret-type>       ::= <type> | "<void>"
     <param-list>     ::= <empty> | <param> <param-list>
     <param>          ::= "(" <param-name> <param-type> [<keyword> ...] ")"
     <param-name>     ::= identifier
     <param-type>     ::= <type>
     <keyword>        ::= "invalidate" | "unchecked" | "ignored" |
                          "optional" | "rest"
     <type>           ::= "<int>" | "<string>" | "<real>" | "<file>" |
                         "<pointer>" | "<object>"
     <glue-code>      ::= string
     <cpp-const-spec> ::= "(" "cpp-constant" <c-name> <type> ")"
     <scheme-name>    ::= identifier
     <symbol-spec>    ::= "(" "symbol" <scheme-name> <c-name> ")"
     <exception-spec> ::= "(" "exception" <scheme-name> <c-name> ")"
     <c-name>         ::= identifier

   <FUNC-NAME> must be the name of the C function to be wrapped.  The
wrapper function will be called `<func-name>_func'.  <RET-TYPE> is the
expected return type of the function and may be `<void>' if it is to be
ignored.  The return type <ret-type> is used to construct the correct
return value for the function's result.  The parameter list
<PARAM-LIST> specifies the names of the parameters for the function and
their types, so that type-checking code can be emitted.

   The option `unchecked' says that no type checking is performed for
this parameter, it will be passed through to the called function.  Note
that this seldom makes sense, except for debug printing or for wrapping
a function aware of Sizzle's Scheme types.

   The option `ignored' tells the processor not to emit type checking
code for this parameter, and that it will not be passed to the wrapped
function.  It will be silently ignored.

   The additional keyword `invalidate', which can be passed as a third
element in a parameter specification, is currently only implemented for
pointer values (type `<pointer>').  It will cause the emission of extra
code which will invalidate the parameter pointer object with a call to
`zzz_invalidate_pointer()'.  This is useful if the wrapped function
performed some action rendering the pointer in the pointer object
useless.  An invalidated pointer cannot be passed to any wrapped
function expecting `<pointer>' arguments after that, because they check
a pointer object's valid flag.  Thus pointer object handling gets a
little bit more safe.

   When `optional' is passed as an option, then the passed parameter is
allowed to be undefined.  You should either specify `ignored' also, to
avoid passing an undefined value to the wrapped function, or you must
give your own <GLUE-CODE> which handles that case properly.

   The option `rest' may be given on the last argument.  When given, it
means that this argument will be the rest argument to which a list of
the remaining argument will be bound.  The type of this variable is
always a list, so no parameter type checking code is emitted.  The type
for this parameter should always be `<object>'.

   The specifications for symbols and exception will create global
variables called <C-NAME> and bind symbol objects with the contents
<SCHEME-NAME> to them.  Also, the variables will be protected from
garbage collection.

   The <CPP-CONST-SPEC> specification creates a Scheme constant which
is bound to the value which gets substituted by the CPP macro <C-NAME>.
The <TYPE> argument is needed to create the constructor for the
constant object.


File: sizzle-embed.info,  Node: A Simple Example strlen,  Next: Manual Glue Code,  Prev: The Specification File,  Up: sizzle-gen-if

A Simple Example
================

   To start with, I want to give a feeling of what `sizzle-gen-if' can
do.  At first, it may seem extremely powerful, but sooner or later you
will find out that the C functions you want to wrap are not as well
suited as in this (contrived) example.

   Take this specification:
     $(function <int> strlen ((string <string>)))

Here we declare a function
   * With the name `strlen'.

   * With the return value `<int>'.

   * Which expects one argument of type `<string>' with the name
     `string'.

When passed through `sizzle-gen-if', this specification is transformed
to this C function.
     /*:doc
       strlen
       (strlen string) => integer
       Apply the C function `strlen' to the following parameters:
       string: string
       doc:*/
     #define FUNC_NAME "strlen"
     static result_t
     strlen_func (zzz_scm_t env, zzz_scm_t string, zzz_scm_t * result)
     {
       static char * s_func_name = FUNC_NAME;
       zzz_scm_t __retval;
     
       CHECK_TYPE (1, string_p (string), zzz_string_type_name);
       {
         int res = strlen (string_val (string));
         __retval = zzz_make_integer (res);
       }
       *result = __retval;
       return RESULT_SUCCESS;
     }
     #undef FUNC_NAME

   Note how the type of the actual parameter is checked for correctnes.
Then the string value is extracted from the string object before calling
the wrapped function, and the result of the function call is stored into
an integer object before returning it.

   The specification and will also generate an init file containing the
following code, which will register the primitive under the name
`strlen' as a function taking exactly one argument.

       zzz_define_function ("strlen",
                            (zzz_prim_t) strlen_func,
                            argv_1_0_0);


File: sizzle-embed.info,  Node: Manual Glue Code,  Next: Pointer arguments,  Prev: A Simple Example strlen,  Up: sizzle-gen-if

Manual Glue Code
================

   The automatically generated wrapper functions are nice, but they are
not as flexible as often is needed.  For example, it is not possible to
specify `<number>' as an argument type and have the script
automatically generate code which selects the value depending on the
actual type of the parameter, which may be integer or real.  Therefor,
the additional parameter <GLUE-CODE> is provided for interface
specifications.  When this code is present, the body of the wrapper
procedure will not be generated, but instead <GLUE-CODE> will be
inserted.  The glue code must assign a return value to the variable
__RETVAL, but the positive effect is that argument type checking is
performed, so the glue code can rely on the fact that the parameters
have the types specified in the interface specification.

   Consider this specification for the primitive `sin':
     $(function <real> sin ((x <number>))
     "
         double d;
     
         if (integer_p (x))
           d = (double) integer_val (x);
         else if (float_p (x))
           d = float_val (x);
         else
           abort ();
         __retval = zzz_make_float (sin (d));
     ")

   The glue code tests which number type the parameter X has, and
performs the correct action according to the type.  When processed with
`sizzle-gen-if', the resulting code looks as follows:

     /*:doc
       sin
       (sin x) => real
       Apply the C function `sin' to the following parameters:
       x: <number>
       doc:*/
     #define FUNC_NAME "sin"
     static result_t
     sin_func (zzz_scm_t env, zzz_scm_t x, zzz_scm_t * result)
     {
       static char * s_func_name = FUNC_NAME;
       zzz_scm_t __retval;
     
       CHECK_TYPE (1, number_p (x), zzz_number_type_name);
       {
         double d;
     
         if (integer_p (x))
           d = (double) integer_val (x);
         else if (float_p (x))
           d = float_val (x);
         else
           abort ();
         __retval = zzz_make_float (sin (d));
       }
       *result = __retval;
       return RESULT_SUCCESS;
     }
     #undef FUNC_NAME

   Additionally, the following initialization file will be created:
       zzz_define_function ("sin",
                            (zzz_prim_t) sin_func,
                            argv_1_0_0);


File: sizzle-embed.info,  Node: Pointer arguments,  Prev: Manual Glue Code,  Up: sizzle-gen-if

Pointer arguments
=================

   A lot of C library functions take pointers as their arguments.  It is
not possible for `sizzle-gen-if' to understand the meaning of all the
possible weird argument passing techniques C programmers have invented.
Thus, `sizzle-gen-if' decides that all data types it cannot understand
are opaque pointers.  This does not catch all cases, but you already
knew that `sizzle-gen-if''s capabilities were limited :-)

   This is an example specification for the C library function
`free()'.  It demonstrates how to use the option keyword `invalidate'
with pointer arguments.

     $(function <void> free ((p <pointer> invalidate)))
   expands to
     /*:doc
       free
       (free p) => *unspecified*
       Apply the C function `free' to the following parameters:
       p: pointer
       doc:*/
     #define FUNC_NAME "free"
     static result_t
     free_func (zzz_scm_t env, zzz_scm_t p, zzz_scm_t * result)
     {
       static char * s_func_name = FUNC_NAME;
       zzz_scm_t __retval;
     
       CHECK_TYPE (1, valid_pointer_p (p), "pointer");
       {
         free (pointer_val (p));
         __retval = zzz_unspecified;
         zzz_invalidate_pointer (p);
       }
       *result = __retval;
       return RESULT_SUCCESS;
     }
     #undef FUNC_NAME

   When `free_func()' returns, the pointer P cannot be used with
wrapper functions anymore, because it has been invalidated.  This is
what you want after you free a pointer, isn't it?  Using this trick,
`sizzle-gen-if' can even make programming with pointers safer.


File: sizzle-embed.info,  Node: Index,  Prev: sizzle-gen-if,  Up: Top

Index
*****

* Menu:

* bool_p:                                Type predicates.
* bool_val:                              Accessor functions.
* bool_var_addr:                         Accessor functions.
* bool_var_p:                            Type predicates.
* car:                                   Accessor functions.
* car_addr:                              Accessor functions.
* cdr:                                   Accessor functions.
* cdr_addr:                              Accessor functions.
* char_p:                                Type predicates.
* char_val:                              Accessor functions.
* cons_p:                                Type predicates.
* constant_p:                            Type predicates.
* constant_val:                          Accessor functions.
* env_p:                                 Type predicates.
* env_val:                               Accessor functions.
* error_p:                               Type predicates.
* except_p:                              Type predicates.
* fdport_fd:                             Accessor functions.
* fdport_has_unget:                      Accessor functions.
* fdport_p:                              Type predicates.
* fdport_unget:                          Accessor functions.
* fixnum_p:                              Type predicates.
* fixnum_val:                            Accessor functions.
* float_p:                               Type predicates.
* float_val:                             Accessor functions.
* form_p:                                Type predicates.
* fport_file:                            Accessor functions.
* fport_p:                               Type predicates.
* func_form_p:                           Accessor functions.
* func_name:                             Accessor functions.
* func_p:                                Type predicates.
* func_param:                            Accessor functions.
* func_ptr:                              Accessor functions.
* gloc_name:                             Accessor functions.
* gloc_p:                                Type predicates.
* gloc_val:                              Accessor functions.
* imm_p:                                 Type predicates.
* immediate_p:                           Type predicates.
* immediate_val:                         Accessor functions.
* int_var_addr:                          Accessor functions.
* int_var_p:                             Type predicates.
* integer_p:                             Type predicates.
* integer_val:                           Accessor functions.
* keyword_name:                          Accessor functions.
* keyword_p:                             Type predicates.
* lambda_args:                           Accessor functions.
* lambda_body:                           Accessor functions.
* lambda_env:                            Accessor functions.
* lambda_file:                           Accessor functions.
* lambda_line:                           Accessor functions.
* lambda_name:                           Accessor functions.
* lambda_p:                              Type predicates.
* list_p:                                Type predicates.
* lloc_p:                                Type predicates.
* lloc_val:                              Accessor functions.
* location_address:                      Accessor functions.
* location_p:                            Type predicates.
* long_p:                                Type predicates.
* long_val:                              Accessor functions.
* macro_code:                            Accessor functions.
* macro_p:                               Type predicates.
* null_p:                                Type predicates.
* number_p:                              Type predicates.
* port_col_number:                       Accessor functions.
* port_line_number:                      Accessor functions.
* port_open_p:                           Accessor functions.
* port_p:                                Type predicates.
* port_ptype:                            Accessor functions.
* port_read_p:                           Accessor functions.
* port_saved_col:                        Accessor functions.
* port_write_p:                          Accessor functions.
* procedure_p:                           Type predicates.
* promise_env:                           Accessor functions.
* promise_expr:                          Accessor functions.
* promise_p:                             Type predicates.
* promise_result:                        Accessor functions.
* promise_thawed:                        Accessor functions.
* regexp_p:                              Type predicates.
* regexp_regex:                          Accessor functions.
* regexp_string:                         Accessor functions.
* regexp_valid:                          Accessor functions.
* ro_:                                   Type predicates.
* ro_bool_var_p:                         Type predicates.
* ro_int_var_p:                          Type predicates.
* ro_str_var_p:                          Type predicates.
* rolocation_p:                          Type predicates.
* rostring_p:                            Type predicates.
* rovector_p:                            Type predicates.
* set_car:                               Accessor functions.
* set_cdr:                               Accessor functions.
* set_symbol_name:                       Accessor functions.
* set_symbol_value:                      Accessor functions.
* sport_len:                             Accessor functions.
* sport_p:                               Type predicates.
* sport_pos:                             Accessor functions.
* sport_size:                            Accessor functions.
* sport_val:                             Accessor functions.
* str_var_len:                           Accessor functions.
* str_var_p:                             Type predicates.
* str_var_size:                          Accessor functions.
* str_var_val:                           Accessor functions.
* string_len:                            Accessor functions.
* string_p:                              Type predicates.
* string_val:                            Accessor functions.
* symbol_name:                           Accessor functions.
* symbol_name_addr:                      Accessor functions.
* symbol_p:                              Type predicates.
* symbol_value:                          Accessor functions.
* symbol_value_addr:                     Accessor functions.
* syntax_p:                              Type predicates.
* syntax_rules:                          Accessor functions.
* TAG <1>:                               Accessor functions.
* TAG:                                   Type predicates.
* tagged_data0:                          Accessor functions.
* tagged_data1:                          Accessor functions.
* tagged_data2:                          Accessor functions.
* tagged_info:                           Accessor functions.
* tagged_p:                              Type predicates.
* tagged_type:                           Accessor functions.
* values_p:                              Type predicates.
* values_val:                            Accessor functions.
* vector_len:                            Accessor functions.
* vector_p:                              Type predicates.
* vector_val:                            Accessor functions.
* zzz_apply:                             Evaluation Functions.
* zzz_bind_bool_variable:                C Variable Handling.
* zzz_bind_int_variable:                 C Variable Handling.
* zzz_bind_scm_variable:                 C Variable Handling.
* zzz_bind_string_variable:              C Variable Handling.
* zzz_cons:                              Object constructors.
* zzz_copy_list:                         Object constructors.
* zzz_copy_tree:                         Object constructors.
* zzz_create_tagged_cell:                Object constructors.
* zzz_define_constant:                   Scheme Variable Handling.
* zzz_define_form:                       Scheme Variable Handling.
* zzz_define_function:                   Scheme Variable Handling.
* zzz_define_port_type:                  Port Functions.
* zzz_define_tagged_type:                Defining Scheme Types.
* zzz_define_variable:                   Scheme Variable Handling.
* zzz_eq:                                Misc C API Functions.
* zzz_equal:                             Misc C API Functions.
* zzz_eqv:                               Misc C API Functions.
* zzz_evaluate:                          Evaluation Functions.
* zzz_evaluate_file:                     Evaluation Functions.
* zzz_evaluate_string:                   Evaluation Functions.
* zzz_finalize:                          Initializing and Finalization.
* zzz_garbage_collect:                   Misc C API Functions.
* zzz_get_variable:                      Scheme Variable Handling.
* zzz_hash_function:                     Hash table handling.
* zzz_hash_ref:                          Hash table handling.
* zzz_hash_set:                          Hash table handling.
* zzz_hashq_ref:                         Hash table handling.
* zzz_hashq_set:                         Hash table handling.
* zzz_hashv_ref:                         Hash table handling.
* zzz_hashv_set:                         Hash table handling.
* zzz_initialize:                        Initializing and Finalization.
* zzz_list_length:                       Misc C API Functions.
* zzz_make_:                             Object constructors.
* zzz_make_bool:                         Object constructors.
* zzz_make_char:                         Object constructors.
* zzz_make_closure:                      Object constructors.
* zzz_make_constant:                     Object constructors.
* zzz_make_continuation:                 Object constructors.
* zzz_make_environment:                  Object constructors.
* zzz_make_error:                        Object constructors.
* zzz_make_exception:                    Object constructors.
* zzz_make_fdport:                       Object constructors.
* zzz_make_fixnum:                       Object constructors.
* zzz_make_float:                        Object constructors.
* zzz_make_fport:                        Object constructors.
* zzz_make_func:                         Object constructors.
* zzz_make_gloc:                         Object constructors.
* zzz_make_integer:                      Object constructors.
* zzz_make_keyword:                      Object constructors.
* zzz_make_lambda:                       Object constructors.
* zzz_make_list:                         Object constructors.
* zzz_make_lloc:                         Object constructors.
* zzz_make_location:                     Object constructors.
* zzz_make_macro:                        Object constructors.
* zzz_make_n_list:                       Object constructors.
* zzz_make_not_available_exception:      Object constructors.
* zzz_make_nstring:                      Object constructors.
* zzz_make_pointer:                      Object constructors.
* zzz_make_pointer_n:                    Object constructors.
* zzz_make_port:                         Object constructors.
* zzz_make_promise:                      Object constructors.
* zzz_make_regexp:                       Object constructors.
* zzz_make_ro_:                          Object constructors.
* zzz_make_ro_nstring:                   Object constructors.
* zzz_make_ro_string:                    Object constructors.
* zzz_make_ro_vector:                    Object constructors.
* zzz_make_sport:                        Object constructors.
* zzz_make_sport_str:                    Object constructors.
* zzz_make_sport_str_n:                  Object constructors.
* zzz_make_sport_str_n_no_copy:          Object constructors.
* zzz_make_string:                       Object constructors.
* zzz_make_symbol:                       Object constructors.
* zzz_make_syntax:                       Object constructors.
* zzz_make_values:                       Object constructors.
* zzz_make_vector:                       Object constructors.
* zzz_mark_cell:                         Defining Scheme Types.
* zzz_port_char_ready_p:                 Port Functions.
* zzz_port_close:                        Port Functions.
* zzz_port_flush:                        Port Functions.
* zzz_port_getc:                         Port Functions.
* zzz_port_print:                        Port Functions.
* zzz_port_putc:                         Port Functions.
* zzz_port_puts:                         Port Functions.
* zzz_port_seek:                         Port Functions.
* zzz_port_tell:                         Port Functions.
* zzz_port_ungetc:                       Port Functions.
* zzz_protect_global:                    C Variable Handling.
* zzz_read_eval_print:                   Evaluation Functions.
* zzz_run:                               Initializing and Finalization.
* zzz_set_arguments:                     Initializing and Finalization.
* zzz_set_top_of_stack:                  Initializing and Finalization.
* zzz_set_variable:                      Scheme Variable Handling.
* zzz_simple_constructor:                Defining Scheme Types.
* zzz_simple_mark:                       Defining Scheme Types.
* zzz_vector_get:                        Accessor functions.
* zzz_vector_put:                        Accessor functions.


