An ML front end for Bigloo

serrano@savigny.inria.fr (Manuel Serrano)
Thu, 3 Mar 1994 11:14:00 GMT

          From comp.compilers

Related articles
An ML front end for Bigloo serrano@savigny.inria.fr (1994-03-03)
| List of all articles for this month |
Newsgroups: comp.compilers
From: serrano@savigny.inria.fr (Manuel Serrano)
Keywords: Scheme, ML, FTP, available
Organization: INRIA * Rocquencourt BP 105 * F-78153 LE CHESNAY CEDEX* France
Date: Thu, 3 Mar 1994 11:14:00 GMT

Ever heard of a compiler that compiles Scheme *and* ML, link them, run
them in a smooth way ! Ever dreamt of a compiler with a complete foreign
interface with C !


                          STOP dreaming, START NOW! using it.
                                    It's name is Bigloo 1.6


Bigloo 1.6 compiles efficiently to C modules written in Scheme,
modules written in Caml (a ML dialect), allows these modules to use C
libraries and C macros, is able to merge them in a standalone
application. Bigloo also offers numerous features: pattern matching,
lexical analyzers generation, objects with Meroon V3.


Bigloo 1.6 is the Scheme compiler, Camloo is the customization above
it that allows to also compile Caml modules. Both may be found on:


          [192.93.2.54] ftp.inria.fr:INRIA/Projects/icsla/Implementations






Here is an example of a program which mix Scheme, ML and C:


First, there is an Caml source file. It builds a list, prints it, reverses it
and re-prints it:


-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----
(* build.ml: a ML source file *)


let l = [1; 2; 3; 4];;


let rec print_list = function [] -> ()
                                                | x :: l -> print_int x; print_list l;;


print_string "l is: "; print_list l; print_newline();;
print_string "l reversed is: "; print_list (nreverse l); print_newline();;
-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----


Of, course, it is not possible in ML to make physical modifications on
lists. For this reason, the function `nreverse' is implemented in Scheme.
In order to perform this, we need an Caml interface:


-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----
(* build.mli: an ML interface *)
value nreverse : 'a list -> 'a list = 1 "nreverse"
;;
-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----


The Scheme source file (a Bigloo module), defines and exports `nreverse'
but to have fun, it also duplicate the ML list in a C structure. This
C structure is the argument of a C function which will print it. It is
to notice that the C structure is allocated from Scheme (in the Bigloo
heap and so, can be reclaimed by the Bigloo's GC).


-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----
;; a Scheme source file
(module __caml_main
      (foreign (include "type.h")
(type el (struct ((int "value")
(el* "next"))
"struct el"))
(void print-el-list (el*) "print_el_list")
(export int fib (int) "fib"))
      (export (c-nreverse x)
(fib x)))


(define (fib x)
      (if (< x 2)
              1
              (+ (fib (- x 1)) (fib (- x 2)))))


(define (c-nreverse l)
      (make-c-list l)
      (if (pair? l)
              (let nr ((l l)
(r '()))
                    (if (null? (cdr l))
                            (begin
                                  (set-cdr! l r)
                                  l)
(let ((cdrl (cdr l)))
(nr cdrl
(begin (set-cdr! l r) l)))))
              l))


(define (make-c-list l)
      (let ((head (make-el)))
            (let loop ((l l)
(c head))
(if (null? l)
(begin
(print "ok, it is done, I print: ")
(print-el-list head))
(let ((new (make-el)))
(el-value-set! c (car l))
(el-next-set! c new)
(loop (cdr l) new))))))
-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----


The C structure is given in a C include file:


-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----
/* type.h: a small C include */
struct el {
int value;
struct el *next;
};
-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----


At the end, the C source file. It traverses the structure, prints it and
for fun invokes the Scheme function fib. Of course Scheme integers are not
C integers, Bigloo has managed (when exporting fib) the coercion to make
this C invocation correct.


-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----
/* el.c: a small stupid C source file */
#include "type.h"


void
print_el_list( l )
struct el *l;
{
printf( "( ");


while( l )
{
printf( "%d ", l->value );
l = l->next;
}
puts( ")\n" );


printf( "Its finish for C, but for fun, I have computed fib: %d\n",
fib( 20 ) );
}
-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----


Of course, we need a Makefile to compile and link all this files:


-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----
# And of course a Makefile...
BIGLOO=bigloo
CC=cc


all: el.o main.o build.o
$(BIGLOO) -o test el.o main.o build.o -extend caml


clean:
\rm -f *.o *.zi test


el.o: el.c
$(CC) -c el.c


main.o: main.scm
$(BIGLOO) -A main.scm


build.o: build.ml build.zi main.zi
$(BIGLOO) -A build.ml


build.zi: build.mli
$(BIGLOO) build.mli


main.zi: main.mli
$(BIGLOO) main.mli
-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----




Ok, we launch the compilation:
$ make
cc -c el.c
bigloo -A main.scm
main.scm:
bigloo build.mli
build.mli:
bigloo main.mli
main.mli:
bigloo -A build.ml
build.ml:
bigloo -o test el.o main.o build.o -extend caml


And now, we are able to run the program:
$ test
l is: 1234
ok, it is done, I print:
( 1 2 3 4 0 )


Its finish for C, but for fun, I have computed fib: 10946
l reversed is: 4321






--Manuel Serrano & Pierre Weis--






--


Post a followup to this message

Return to the comp.compilers page.
Search the comp.compilers archives again.