Name:
externalproc
binds an external code to a Sollya procedure
Library names:
sollya_obj_t sollya_lib_externalprocedure(sollya_externalprocedure_type_t,
sollya_externalprocedure_type_t *,
int, char *, void *);
sollya_obj_t sollya_lib_externalprocedure_with_data(
sollya_externalprocedure_type_t,
sollya_externalprocedure_type_t *,
int, char *, void *, void *,
void (*)(void *));
Usage:
externalproc(identifier, filename, argumenttype -> resulttype) : (identifier type, string, type type, type type) -> void
Parameters:
- identifier represents the identifier the code is to be bound to
- filename of type string represents the name of the object file where the code of procedure can be found
- argumenttype represents a definition of the types of the arguments of the Sollya procedure and the external code
- resulttype represents a definition of the result type of the external code
Description:
- externalproc allows for binding the Sollya identifier identifier to an
external code. After this binding, when Sollya encounters identifier
applied to a list of actual parameters, it will evaluate these parameters and
call the external code with these parameters. If the external code indicated
success, it will receive the result produced by the external code, transform
it to Sollya's internal representation and return it.
In order to allow correct evaluation and typing of the data in parameter and
in result to be passed to and received from the external code, externalproc
has a third parameter argumenttype -> resulttype. Both argumenttype and
resulttype are one of void, constant, function, object, range, integer,
string, boolean, list of constant, list of function, list of object,
list of range, list of integer, list of string, list of boolean.
It is worth mentionning that the difference between the data and
result type function and the type object is minimal and due to
support of legacy Sollya code. Both Sollya functions and Sollya
objects are transferred from and to the external procedure thru the C
type sollya_obj_t. The difference is that
Sollya will check that a certain object is a mathematical function
when function is used as a type, and will skip this test if the
object type is used. Similarly, Sollya relies on an object produced
by the external procedure to be a mathematical function when function
is used and will not make this assumption for object.
If upon a usage of a procedure bound to an external procedure the type of the
actual parameters given or its number is not correct, Sollya produces a type
error. An external function not applied to arguments represents itself and
prints out with its argument and result types.
The external function is supposed to return an integer indicating success. It
returns its result depending on its Sollya result type as follows. Here, the
external procedure is assumed to be implemented as a C function.
- If the Sollya result type is void, the C function has no pointer
argument for the result.
- If the Sollya result type is constant, the first argument of the
C function is of C type mpfr_t *, the result is returned by affecting
the MPFR variable.
- If the Sollya result type is function, the first argument of the
C function is of C type sollya_obj_t *, the result is returned by
affecting the sollya_obj_t variable.
- If the Sollya result type is object, the first argument of the
C function is of C type sollya_obj_t *, the result is returned by
affecting the sollya_obj_t variable.
- If the Sollya result type is range, the first argument of the C function
is of C type mpfi_t *, the result is returned by affecting the MPFI
variable.
- If the Sollya result type is integer, the first argument of the
C function is of C type int *, the result is returned by affecting the
int variable.
- If the Sollya result type is string, the first argument of the
C function is of C type char **, the result is returned by the char *
pointed with a new char *.
- If the Sollya result type is boolean, the first argument of the
C function is of C type int *, the result is returned by affecting the
int variable with a boolean value.
- If the Sollya result type is list of type, the first argument of the
C function is of a C type depending on the Sollya return type:
- For a list of constant: sollya_constant_list_t *
- For a list of function: sollya_obj_list_t *
- For a list of object: sollya_obj_list_t *
- For a list of range: sollya_constant_list_t *
- For a list of integer: sollya_int_list_t *
- For a list of string: sollya_string_list_t *
- For a list of boolean: sollya_boolean_list_t *
The external procedure affects its possible pointer argument if and only if
it succeeds. This means, if the function returns an integer indicating
failure, it does not leak any memory to the encompassing environment.
The external procedure receives its arguments as follows: If the Sollya
argument type is void, no argument array is given. Otherwise the C function
receives a C void ** argument representing an array of size equal to the
arity of the function where each entry (of C type void *) represents a value
with a C type depending on the corresponding Sollya type.
- If the Sollya type is constant, the void * is to be cast to mpfr_t *.
- If the Sollya type is function, the void * is to be cast to
sollya_obj_t.
- If the Sollya type is object, the void * is to be cast to sollya_obj_t.
- If the Sollya type is range, the void * is to be cast to mpfi_t *.
- If the Sollya type is integer, the void * is to be cast to int *.
- If the Sollya type is string, the void * is to be cast to char *.
- If the Sollya type is boolean, the void * is to be cast to int *.
- If the Sollya type is list of type, the void * is to be cast to a list
of a type depending on the type of the list argument:
- For a list of constant: sollya_constant_list_t
- For a list of function: sollya_obj_list_t
- For a list of object: sollya_obj_list_t
- For a list of range: sollya_interval_list_t
- For a list of integer: sollya_int_list_t
- For a list of string: sollya_string_list_t
- For a list of boolean: sollya_boolean_list_t
The external procedure is not supposed to alter the memory pointed by its
array argument void **.
In both directions (argument and result values), empty lists are represented
by NULL pointers.
Similarly to internal procedures, externally bounded procedures can be
considered to be objects inside Sollya that can be assigned to other
variables, stored in list etc.
- The user should be aware that they may use the Sollya library in external
codes to be dynamically bound to Sollya using externalproc. On most systems,
it suffices to include the header of the Sollya library into the source code
of the external procedure. Linking with the actual Sollya library is not
necessary on most systems; as the interactive Sollya executable contains a
superset of the Sollya library functions. On some systems, linking with the
Sollya library or some of its dependencies may be necessary.
In particular, the Sollya library – and, of course, its header file –
contain a certain set of functions to manipulate lists with elements of
certain types, such as sollya_constant_list_t, sollya_obj_list_t and so on.
As explained above, these types are passed in argument to (and received back
thru a reference from) an external procedure. These list manipulation
functions are not strictly necessary to the use of the Sollya library in
free-standing applications that do not use the functionality provided with
externalproc. They are therefore provided as-is without any further
documentation, besides the comments given in the Sollya library header file.
- The dynamic object file whose name is given to externalproc for binding of
an external procedure may also define a destructor function
int sollya_external_lib_close(void). If Sollya finds such a destructor
function in the dynamic object file, it will call that function when closing
the dynamic object file again. This happens when Sollya is terminated or when
the current Sollya session is restarted using restart. The purpose of the
destructor function is to allow the dynamically bound code to free any memory
that it might have allocated before Sollya is terminated or restarted.
The dynamic object file is not necessarily needed to define a destructor
function. This ensure backward compatibility with older Sollya external
library function object files.
When defined, the destructor function is supposed to return an integer
value indicating if an error has happened. Upon success, the destructor
functions is to return a zero value, upon error a non-zero value.
Example 1:
> bashexecute("gcc -fPIC -Wall -c externalprocexample.c");
> bashexecute("gcc -fPIC -shared -o externalprocexample externalprocexample.o");
> externalproc(foo, "./externalprocexample", (integer, integer) -> integer);
> foo;
foo
> foo(5, 6);
11
> verbosity = 1!;
> foo();
Warning: at least one of the given expressions or a subexpression is not correctly typed
or its evaluation has failed because of some error on a side-effect.
error
> a = foo;
> a(5,6);
11
See also: library,
libraryconstant,
externalplot,
bashexecute,
void,
constant,
function,
range,
integer,
string,
boolean,
list of