TinyScheme FFI

I started to experiment with using TinyScheme to control a libreCMC system, but then discovered that TinyScheme doesn’t actually come built-in with a system interface, other than basic input/output (from stdio.h). This is not really a deficiency, as TinyScheme was intended to be embedded in a variety of systems and applications. TinyScheme has a Foreign Function Interface (FFI) allowing us to turn C functions into scheme functions, so adding in more system functions should in principle be fairly simple.

One difficulty, though, is that the examples in the documentation did not actually match the FFI in the release. So, I had to spend some quality time in the header files. I was then able to modify the examples to work. This C program loads and runs a scheme file called myscheme.scm, while importing a C function called square, which, of course, squares a number:

#include "tinyscheme/scheme.h"
#include "tinyscheme/scheme-private.h"

pointer square(scheme *sc, pointer args) {
  if(args!=sc->NIL) {
    if(sc->vptr->is_number(sc->vptr->pair_car(args))) {
      double v=sc->vptr->rvalue(sc->vptr->pair_car(args));
      return sc->vptr->mk_real(sc,v*v);
    }
  }
  return sc->NIL;
}

int main() {
  scheme * sc;

  FILE *fptr;
  // initialize the scheme invironment
  sc = scheme_init_new();
  // set output to go to STDOUT by default
  scheme_set_output_port_file(sc, stdout);
  // Load the init file
  fptr = fopen("/usr/lib/tinyscheme/init.scm", "r");
  scheme_load_file(sc, fptr);
  fclose(fptr);

  // Import square fn
  sc->vptr->scheme_define(sc,
  sc->global_env,
  sc->vptr->mk_symbol(sc,"square"),
  sc->vptr->mk_foreign_func(sc, square));
 
  // Load my scheme program
  fptr = fopen("myscheme.scm", "r");
  scheme_load_file(sc, fptr);
  fclose(fptr);
  // de-initialize the scheme environment
  scheme_deinit(sc);
  return 0;
}

And here is the scheme program:

(display (square 4))
(newline)

And here is execution:

christopher@evenstar:~/Devel/embedded-ts$ gcc -o loader -DUSE_DL loader.c -ltinyscheme
christopher@evenstar:~/Devel/embedded-ts$ ./loader 
16.0

Next I should be able to add functions from <stdlib.h>, e.g., system() to call shell commands.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s