Xen

The Xen package provides macros and procedures making it possible for the same C code to support several different embedded (or extension) languages. Currently supported are s7, Ruby, and Forth.

Here's a program that defines a function (named "fnc" in the extension language) that takes an integer argument and increments it, a variable (named "var" in the extension language) that is initialized to 32, a constant (named "twelve") that has the value 12, then places you in a read-eval-print loop:

#include <stdio.h>
#include "xen.h"

static XEN orig_function(XEN argument)
{
  XEN_ASSERT_TYPE(XEN_INTEGER_P(argument), argument, XEN_ONLY_ARG, "fnc", "an integer");
  fprintf(stdout, "argument is %d\n", XEN_TO_C_INT(argument));
  return(C_TO_XEN_INT(XEN_TO_C_INT(argument) + 1));
}

XEN_NARGIFY_1(function, orig_function);

static XEN variable;

int main(int argc, char **argv)
{
  xen_initialize();

  XEN_DEFINE_VARIABLE("var", variable, C_TO_XEN_INT(32));
  XEN_DEFINE_CONSTANT("twelve", 12, "this is 12");
  XEN_DEFINE_PROCEDURE("fnc", function, 1, 0, 0, "this is our function");

  fprintf(stdout, "we're running: %s\n", xen_version());

  xen_repl(argc, argv);
  return(0);
}

The "XEN_ARGIFY" step is needed for those languages that assume one calling sequence for a C-defined function; we have to wrap up the actual call in whatever sequence the extension language wants.

Currently constants are assumed to be integers. Type checks are handled by macros such as XEN_INTEGER_P; type conversions by macros such as XEN_TO_C_INT or C_TO_XEN_INT.