Adding Lisp Functions Coded in C

Programs that heavily refer to C include files or frequently access arrays perform better or are more clearly described if written in C or other languages rather than in EusLisp. EusLisp provides the way to link programs coded in C.

If you want to define EusLisp function written in C, each EusLisp-callable C-function must be coded to accept three arguments: the context pointer, the number of arguments and the pointer to the Lisp argument block. These arguments must be named as ctx, n and argv, since the macros in c/eus.h assume these names. The C program must include *eusdir*/c/eus.h. The programmer should be familiar with the types and macros described there. The entry function should be named by the basename of the source file.

A sample code for C function AVERAGE which computes the arithmetic average of arbitrary number of floats is shown below. In this example, you can see how to get float values from arguments, how to make the pointer of a float, how to set a pointer in the special variable AVERAGE, and how to define a function and a symbol in the entry function ave. Compile this program by 'cc -c -Dsun4 -DSolaris2 -K pic'. -Dsun4 and -DSolaris2 are needed to chose proper definitions in c/eus.h. -K pic is needed to let the c compiler generate position independent code necessary for the loadable shared object. Then the resulted '.o' file can be loaded into EusLisp. More complete examples can be found in *eusdir*/clib/*.c, which are defined and loaded in the same manner described here.

/* ave.c */
/* (average &rest numbers) */
#include "/usr/local/eus/c/eus.h"
static pointer AVESYM;
pointer AVERAGE(ctx,n,argv)
context *ctx;
int n;
pointer argv[];
{ register int i;
  float sum=0.0, a, av;
  pointer result;
  numunion nu;
  for (i=0; i<n; i++) {
    a=ckfltval(argv[i]);
    sum += a;} /*get floating value from args*/
  av=sum/n;
  result=makeflt(av);
  AVESYM->c.sym.speval=result;  /*kindly set the result in symbol*/
  return(result);}

ave(ctx,n,argv)
context *ctx;
int n;
pointer argv[];
{ char *p;
  p="AVERAGE";
  defun(ctx,p,argv[0],AVERAGE);
  AVESYM=intern(ctx,p,strlen(p),userpkg); /* make a new symbol*/
  }

k-okada 2013-05-21