Friday, October 29, 2010

Update, E' & contains

I've been working heavily on Digamma, to the point where I've not blogged about it in a year, so here's a quick update.

Vesta is working well; so well that I don't have any other scheme interpreters installed on any of my machines anymore. That's a good sign, since I use Scheme & C for just about everything. Vesta itself is just about as fast as you can possible get with an AST walking interpreter; a simple fib program, that computes & prints the Fibbonacci values for 3,4,5,10,15,20 runs in about 0.245u, where as C runs at 0.00u and natively compiled PreDigamma runs at 0.01u. I don't have timings for Ceres yet, as I'm still working on that.


E'

Enyo, the PreDigamma compiler, is a rather large piece of software; it has a type inference engine, nice code generation back-end (so that PreDigamma can target other systems, such as Inferno's Limbo or even Plan9's ken cc). This isn't fun though, so I thought about having some fun. Enter E': a tiny compiler for PreDigamma to C. It's 400 or so lines, a tail call optimizer & support for PreDigamma save for macros, syntax,c-macros, c-syntax, FFI & types. That's quite a few features missing, but it works well; I've been using it for quite a few little utilities here & there, and it compiles nicely. For instance, it turns this:


(def fib (fn (t i j n)

 (if (<= n 1)

  i

 (fib i (+ i j) t (- n 1)))))


into this:


SExp *
fib(SExp *t, SExp *i, SExp *j,SExp *n)
{
   SExp *ret = nil;
   int s1 = 0;
   while(!s1)
   {
      SExp *it0 = flte(list(2,n,makeinteger(1)));
      if(it0 == nil || it0->type == NIL || ((it0->type == BOOL || it0->type == GOAL) && it0->object.c))
      {
         s1 = 1;
         ret = i;
      }
      else
      {
          t = i;
          i = fplus(list(2,i,j));
          j = t;
         n = fsubt(list(2,n,makeinteger(1)));
      }
    }
    return ret;
}

Which is pretty nice, and quite speedy.


Contains

There's a new primitive in Digamma, called contains. This is analogous to Python's in, and it works on all collexions:

contains c : COLLEXION v : ATOMIC [key-or-value : BOOL] => BOOL

 the key-or-value part is for if you're testing a dict: you may want to test whether it has the key v or the value v, so there's a boolean flag for that. Nice, semantically simple & clean; Total positive in my book.