Node:Dia Primitives, Next:Dia Hook, Previous:Dia Smobs, Up:Extending Dia
Once the details of object representation are decided, writing the primitive function code that you need is usually straightforward.
A primitive is simply a C function whose arguments and return value are
all of type SCM
, and whose body does whatever you want it to do.
As an example, here is a possible implementation of the square?
primitive:
#define FUNC_NAME "square?" static SCM square_p (SCM shape) { struct dia_guile_shape * guile_shape; /* Check that arg is really a shape SMOB. */ SCM_VALIDATE_SHAPE (SCM_ARG1, shape); /* Access Scheme-specific shape structure. */ guile_shape = SCM_SMOB_DATA (shape); /* Find out if underlying shape exists and is a square; return answer as a Scheme boolean. */ return SCM_BOOL (guile_shape->c_shape && (guile_shape->c_shape->type == DIA_SQUARE)); } #undef FUNC_NAME
Notice how easy it is to chain through from the SCM shape
parameter that square_p
receives -- which is a SMOB -- to the
Scheme-specific structure inside the SMOB, and thence to the underlying
C structure for the shape.
In this code, SCM_SMOB_DATA
and SCM_BOOL
are macros from
the standard Guile API. SCM_VALIDATE_SHAPE
is a macro that you
should define as part of your SMOB definition: it checks that the passed
parameter is of the expected type. This is needed to guard against
Scheme code using the square?
procedure incorrectly, as in
(square? "hello")
; Scheme's latent typing means that usage errors
like this must be caught at run time.
Having written the C code for your primitives, you need to make them
available as Scheme procedures by calling the scm_c_define_gsubr
function. scm_c_define_gsubr
(REFFIXME) takes arguments that
specify the Scheme-level name for the primitive and how many required,
optional and rest arguments it can accept. The square?
primitive
always requires exactly one argument, so the call to make it available
in Scheme reads like this:
scm_c_define_gsubr ("square?", 1, 0, 0, square_p);
For where to put this call, see the subsection after next on the structure of Guile-enabled code (see Dia Structure).