Although the EDEN interpreter has a number of pre-defined functions, such as substr or writeln, and allows the user to define his own functions within the EDEN environment, the user may find restrictions in special purpose applications, such as a graphics application. The user may find some useful functions which are already written in C. Unfortunately, with the current implementation, there are no ways for the EDEN user to call C (or other languages) functions without recompiling the interpreter.
Some efforts had been done to minimise the difficulties of interfacing with C functions so that the user can call a C function directly from the EDEN environment. A built-in EDEN/C interface can bind a C function to an EDEN name. However, due to some technical problems and the differences in the method of argument passing, not all C functions can be called by the EDEN interpreter through the EDEN/C interface.
getchar()
) unless they are
rewritten as true C functions.
Despite these limitations, the EDEN/C interface can handle a large number
of existing C functions. Sometimes, the user can write a simple C function
to ``bridge'' with a C function excluded by the limitations. For instance,
the user can write a C function, e.g. BridgeFunc
, to interface with the
actual C function, e.g. ActualFunc
, which requires a structure as its
argument:
struct point { int x; int y; }; ActualFunc(struct point p) { ... } BridgeFunc(intx, int y) { struct point p; p.x = x; p.y = y; return ActualFunc(p); }
Then the bridge function is bound instead of the actual function.
$PUBLIC/tkeden/Misc/customlib.h
, to add the C function
declarations which must be enclosed in the two lines:
#if INCLUDE == 'H' #endifFor example,
#if INCLUDE == 'H' extern system(); extern fprintf(); extern char * fgets(); extern double sin(); extern double cos(); #endif
customlib.h
, add the binding information entry of
the form:
{ "EDEN_name", (int(*)())C_function_name },where EDEN_name is a valid EDEN identifier and C_function_name is the C function name declared in (1). The two names can be different.
(int(*)())
''
is used to cast the C function to an integer function. Don't forget the
commas at the end.
#if INCLUDE == 'T' #endifFor example:
#if INCLUDE == 'T' { "system", system }, { "fprintf", fprintf }, { "fgets", (int(*)())fgets }, /* ... etc ... */ #endifIf the function returns a double precision floating point, the binding information shall be enclosed in
#if INCLUDE == 'R' #endifFor example:
#if INCLUDE == 'R' { "sin", sin }, { "cos", cos }, /* ... etc ... */ #endif
$PUBLIC/tkeden/INSTALL
. Don't forget to add the links in
Imakefile
(or Makefile
as appropriate)
if the new functions added require
links to object libraries other than what have already included.
A set of macros is defined, at the beginning of customlib.h
, to reduce
the complexity of binding C functions to EDEN names. These macros are
SameFunc
, Function
, SameReal
,
RealFunc
, and SpecialF
:
SameFunc(
Name)
Function(
Ename,Cname)
SpecialF(
Ename,Type,Cname)
RealFunc(
Ename,Cname)
SameReal(
Name)
These macros reduces the two-part information into a single macro. To
specify a binding, just append the macros at the end of customlib.h
. For
example:
/* customlib.h */ ... SameFunc(system) SameFunc(fprintf) SpecialF(fopen,FILE *,fopen) Function(getchar,my_getchar) RealFunc(sin,sin) SameReal(cos) ...
No white space is allowed in the macros (except in Type
), and
no other punctuations (including commas and semi-colons, but excluding
comments) can follow these macros.