Adding C Library Functions to EDEN

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.

Limitations

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.

To bind a C function

  1. The user must edit the header file, $PUBLIC/tkeden/Misc/customlib.h, to add the C function declarations which must be enclosed in the two lines:
    #if INCLUDE == 'H'
    #endif
    
    For example,
    #if INCLUDE == 'H'
            extern system();
            extern fprintf();
            extern char * fgets();
            extern double sin();
            extern double cos();
    #endif
    
  2. In the same file, 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.
    The binding information must enclosed in
    #if INCLUDE == 'T'
    #endif
    
    For example:
    #if INCLUDE == 'T'
            { "system", system },
            { "fprintf", fprintf },
            { "fgets", (int(*)())fgets },
            /* ... etc ... */
    #endif
    
    If the function returns a double precision floating point, the binding information shall be enclosed in
    #if INCLUDE == 'R'
    #endif
    
    For example:
    #if INCLUDE == 'R'
            { "sin", sin },
            { "cos", cos },
            /* ... etc ... */
    #endif
    
  3. Recompile EDEN following instructions in the file $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)
Bind a C function named as Name to the EDEN name identical to Name. The value returned by the C function must be of integer type.
Function(Ename,Cname)
Bind a C function named as Cname to the EDEN name Ename. The value returned by the C function must be of integer type.
SpecialF(Ename,Type,Cname)
Bind a C function named as Cname to the EDEN name Ename. Type specifies the type of value returned by the C function.
RealFunc(Ename,Cname)
Bind a C function named as Cname to the EDEN name Ename. The C function must be a double precision floating point function.
SameReal(Name)
Bind a C function named as Name to the EDEN name identical to Name. The C function must be a double precision floating point function.

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)
...

Warning

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.


[FORWARD] [HOME] [UP] [HELP]