@c @include ../sources/data-rep.texi
@node Scheme data representation
@chapter Scheme data representation


@page
@node Relationship between Scheme and C functions
@chapter Relationship between Scheme and C functions

@c Chapter contents contributed by Thien-Thi Nguyen <ttn@gnu.org>.

Scheme procedures marked "primitive functions" have a regular interface
when calling from C, reflected in two areas: the name of a C function, and
the convention for passing non-required arguments to this function.

@c Although the vast majority of functions support these relationships,
@c there are some exceptions.

@menu
* Transforming Scheme name to C name::
* Structuring argument lists for C functions::
@c * Exceptions to the regularity::
@end menu

@node Transforming Scheme name to C name
@section Transforming Scheme name to C name

Normally, the name of a C function can be derived given its Scheme name,
using some simple textual transformations:

@itemize @bullet

@item
Replace @code{-} (hyphen) with @code{_} (underscore).

@item
Replace @code{?} (question mark) with "_p".

@item
Replace @code{!} (exclamation point) with "_x".

@item
Replace internal @code{->} with "_to_".

@item
Replace @code{<=} (less than or equal) with "_leq".

@item
Replace @code{>=} (greater than or equal) with "_geq".

@item
Replace @code{<} (less than) with "_less".

@item
Replace @code{>} (greater than) with "_gr".

@item
Replace @code{@@} with "at". [Omit?]

@item
Prefix with "gh_" (or "scm_" if you are ignoring the gh interface).

@item
[Anything else?  --ttn, 2000/01/16 15:17:28]

@end itemize

Here is an Emacs Lisp command that prompts for a Scheme function name and
inserts the corresponding C function name into the buffer.

@example
(defun insert-scheme-to-C (name &optional use-gh)
  "Transforms Scheme NAME, a string, to its C counterpart, and inserts it.
Prefix arg non-nil means use \"gh_\" prefix, otherwise use \"scm_\" prefix."
  (interactive "sScheme name: \nP")
  (let ((transforms '(("-"  . "_")
                      ("?"  . "_p")
                      ("!"  . "_x")
                      ("->" . "_to_")
                      ("<=" . "_leq")
                      (">=" . "_geq")
                      ("<"  . "_less")
                      (">"  . "_gr")
                      ("@"  . "at"))))
    (while transforms
      (let ((trigger (concat "\\(.*\\)"
                             (regexp-quote (caar transforms))
                             "\\(.*\\)"))
            (sub (cdar transforms))
            (m nil))
        (while (setq m (string-match trigger name))
          (setq name (concat (match-string 1 name)
                             sub
                             (match-string 2 name)))))
      (setq transforms (cdr transforms))))
  (insert (if use-gh "gh_" "scm_") name))
@end example

@node Structuring argument lists for C functions
@section Structuring argument lists for C functions

The C function's arguments will be all of the Scheme procedure's
argumements, both required and optional; if the Scheme procedure takes a
``rest'' argument, that will be a final argument to the C function.  The
C function's arguments, as well as its return type, will be @code{SCM}.

@c @node Exceptions to the regularity
@c @section Exceptions to the regularity
@c
@c There are some exceptions to the regular structure described above.

@page
@node I/O internals
@chapter I/O internals

@xref{C Port Interface}.

@xref{Port Implementation}.

@node libguile error handling
@chapter libguile error handling

@example
Error handling is based on catch and throw.  Errors are always thrown with
a key and four arguments:

key: a symbol which indicates the type of error.  The symbols used
by libguile are listed below.

subr: the name of the procedure from which the error is thrown, or #f.

message: a string (possibly language and system dependent) describing the
error.  The tokens %s and %S can be embedded within the message: they
will be replaced with members of the args list when the message is
printed.  %s indicates an argument printed using "display", while %S
indicates an argument printed using "write".  message can also be #f,
to allow it to be derived from the key by the error handler (may be
useful if the key is to be thrown from both C and Scheme).

args: a list of arguments to be used to expand %s and %S tokens in message.
Can also be #f if no arguments are required.

rest: a list of any additional objects required. e.g., when the key is
'system-error, this contains the C errno value.  Can also be #f if no
additional objects are required.

In addition to catch and throw, the following Scheme facilities are
available:

(scm-error key subr message args rest): throw an error, with arguments
as described above.

(error msg arg ...)  Throw an error using the key 'misc-error.  The error
message is created by displaying msg and writing the args.

The following are the error keys defined by libguile and the situations
in which they are used:

error-signal: thrown after receiving an unhandled fatal signal such as
SIGSEV, SIGBUS, SIGFPE etc.  The "rest" argument in the throw contains
the coded signal number (at present this is not the same as the usual
Unix signal number).

system-error: thrown after the operating system indicates an error
condition.  The "rest" argument in the throw contains the errno value.

numerical-overflow: numerical overflow.

out-of-range: the arguments to a procedure do not fall within the
accepted domain.

wrong-type-arg: an argument to a procedure has the wrong thpe.

wrong-number-of-args: a procedure was called with the wrong number of
arguments.

memory-allocation-error: memory allocation error.

stack-overflow: stack overflow error.

regex-error: errors generated by the regular expression library.

misc-error: other errors.

C support
=========

SCM scm_error (SCM key, char *subr, char *message, SCM args, SCM rest)

Throws an error, after converting the char * arguments to Scheme strings.
subr is the Scheme name of the procedure, NULL is converted to #f.
Likewise a NULL message is converted to #f.

The following procedures invoke scm_error with various error keys and
arguments.  The first three call scm_error with the system-error key
and automatically supply errno in the "rest" argument:  scm_syserror
generates messages using strerror,  scm_sysmissing is used when
facilities are not available.  Care should be taken that the errno
value is not reset (e.g., due to an interrupt.)

void scm_syserror (char *subr);
void scm_syserror_msg (char *subr, char *message, SCM args);
void scm_sysmissing (char *subr);

void scm_num_overflow (char *subr);
void scm_out_of_range (char *subr, SCM bad_value);
void scm_wrong_num_args (SCM proc);
void scm_wrong_type_arg (char *subr, int pos, SCM bad_value);
void scm_memory_error (char *subr);
static void scm_regex_error (char *subr, int code); (only used in rgx.c).

Exception handlers can also be installed from C, using
scm_internal_catch, scm_lazy_catch, or scm_stack_catch from
libguile/throw.c.  These have not yet been documented, however the
source contains some useful comments.
@end example

@page
@node snarfing
@chapter snarfing
