type inferencer/compiler

"Yury Sulsky" <[email protected]> Tue, 25 Apr 2006 01:56:04 -0400
Newsgroups gmane.lisp.lush.devel
Message-ID <[email protected]>
Hi everyone,

This took me way too long, mostly because I don't know what I'm doing.
I've attached my latest attempt.

A few notes:
  1. I didn't keep compatibility with Lush in mind.
  2. The compiler generates lexical scoping code; dynamic scoping
makes type inference hard.
  3. None of the types/macros I used are defined on the C side yet.
  4. Macro expansion and flambda aren't implemented yet
  5. Support for objects/matrices/htables is missing
  6. Lots of primitives are missing (I should really add progn...)
  7. I'm relying on an external GC, so I never free()

In short, it really needs to be fleshed out. I haven't done a lot of
testing, but what is there seems to work pretty well. One issue to
consider is that global variables are looked up by the runtime, so you
have to box/unbox them and you can't open-code calls to global
functions.

I was thinking that when you compile an entire module at a time, you
have the option of setting the globals to be read-only from the
outside. To that end, I added a third argument to defparameter:
specifying 'module tells the compiler not to worry about that
parameter being overwritten from outside the module (this'd only be
enabled when compiling entire modules, though those aren't implemented
yet either).

Here are some inputs/outputs (below).
Yury


====================================
(defparameter fac (lambda (n)
                                         (if (= 0 n)
                                             1
                                           (* n (fac (- n 1)))))
                       module)
====================================
#include <stdio.h>

/* forward declarations */

int fac166__lambda (int n);
box_t fac166__boxed (box_t * args, int nargs, closure_t cl);
closure_t fac;

/* top level definitions */

struct closure closure__fac166 = { &fac166__lambda, &fac166__boxed };
int
fac166__lambda (int n)
{
  int ifret188;

  if ((0) == (n))
  {
    ifret188 = 1;
  }
  else
  {
    ifret188 = (n) * (fac166__lambda ((n) - (1)));
  }
  return ifret188;
}

void
module_init ()
{
  /* initialization code */


  /* top level statements */

  {
    fac = (closure_t) & closure__fac166;
    ;
  }
}

====================================
(defparameter fac (lambda (n)
                                         (if (= 0 n)
                                             1
                                           (* n (fac (- n 1)))))
                       global)
====================================
#include <stdio.h>

/* forward declarations */

int fac114__lambda (int n);
box_t fac114__boxed (box_t * args, int nargs, closure_t cl);
symb_t fac;

/* top level definitions */

struct closure closure__fac114 = { &fac114__lambda, &fac114__boxed };
int
fac114__lambda (int n)
{
  int ifret136;

  if ((0) == (n))
  {
    ifret136 = 1;
  }
  else
  {
    ifret136 = (n) * (fac114__lambda ((n) - (1)));
  }
  return ifret136;
}

void
module_init ()
{
  /* initialization code */

  fac = SYMB_INTERN ("fac");

  /* top level statements */

  {
    BOX_SET_VAL (SYMB_VALUE (fac), (closure_t) & closure__fac114, closure_t);
    ;
  }
}

====================================
(let* ((weird (lambda (x)
                     (lambda (y)
                       (lambda (z)
                         (+ x y z))))))
             (((weird 1) 2) 3))))
====================================
#include <stdio.h>

/* forward declarations */

struct closure__anonfn122;
int anonfn122__lambda (int z, struct closure__anonfn122 *closure__);
box_t anonfn122__boxed (box_t * args, int nargs, closure_t cl);

struct closure__anonfn121;
closure_t anonfn121__lambda (int y__stack,
                             struct closure__anonfn121 *closure__);
box_t anonfn121__boxed (box_t * args, int nargs, closure_t cl);

closure_t anonfn117__lambda (int x__stack);
box_t anonfn117__boxed (box_t * args, int nargs, closure_t cl);

/* top level definitions */

struct closure__anonfn122
{
  int (*__lambda) (int z, struct closure__anonfn122 * closure__);
    box_t (*__boxed) (box_t *, int, closure_t *);
  int *y;
  int *x;
};
int
anonfn122__lambda (int z, struct closure__anonfn122 *closure__)
{
  return (*(closure__->x)) + (*(closure__->y)) + (z);
}
struct closure__anonfn121
{
  closure_t (*__lambda) (int y__stack, struct closure__anonfn121 * closure__);
  box_t (*__boxed) (box_t *, int, closure_t *);
  int *x;
};
closure_t
anonfn121__lambda (int y__stack, struct closure__anonfn121 *closure__)
{
  int *y = (int *) malloc (sizeof (int));
  struct closure__anonfn122 *closure134 =
    (struct closure__anonfn122 *) malloc (sizeof (struct closure__anonfn122));
  *y = y__stack;
  closure134->__lambda = anonfn122__lambda;
  closure134->__boxed = anonfn122__boxed;
  closure134->y = &(*y);
  closure134->x = &(*(closure__->x));
  return (closure_t) closure134;
}
struct closure closure__anonfn117 = { &anonfn117__lambda, &anonfn117__boxed };
closure_t
anonfn117__lambda (int x__stack)
{
  int *x = (int *) malloc (sizeof (int));
  struct closure__anonfn121 *closure141 =
    (struct closure__anonfn121 *) malloc (sizeof (struct closure__anonfn121));
  *x = x__stack;
  closure141->__lambda = anonfn121__lambda;
  closure141->__boxed = anonfn121__boxed;
  closure141->x = &(*x);
  return (closure_t) closure141;
}

void
module_init ()
{
  /* initialization code */


  /* top level statements */

  {
    int letret115;

    {
      closure_t weird;
      closure_t closure145;
      closure_t closure149;
      closure_t closure150;

      weird = (closure_t) & closure__anonfn117;
      closure145 = weird;

// BUG: it should open-code this call; this should be
//    closure149 = anonfn117__lambda (1);
// also it shouldn't be anonfn117 but weird117.
// Probably a simple bug, I'll fix it soon

     closure149 = ((closure_t (*)(int)) ((closure145)->__lambda)) (1);

      closure150 =
        ((closure_t (*)(int)) ((closure149)->__lambda)) (2, closure149);
      letret115 = ((int (*)(int)) ((closure150)->__lambda)) (3, closure150);
    }
    letret115;
  }
}
blah2.lsh (application/octet-stream, 41.8 KB) - not displayed