Re: [linux-audio-dev] [semi-OT] EEL 0.1.0

From: Kjetil Svalastog Matheussen <k.s.matheussen@email-addr-hidden>
Date: Sat Jan 15 2005 - 15:46:22 EET

Steve Harris:
> Yep, for performance coding I would say SC is the best bet, I've seen a
> live coding performance, and it was very impressive. Almost enough to make
> me want to use emacs. Almost ;)
>
> I was thinking of a live C compiler for prototyping and testing
> purposes.
>

What a coincidence! I'm just working on something like that.
This is what you are looking for:

http://tinyurl.com/5bekn

The url above is pointing to the cvs-entry of the file eval-c.scm in the
snd sound editor. Eval-c is c-code using s-expressions (which I know you
hate, allthough I don't know why, perhaps you are crazy...), compiled,
linked and run on the fly. Place the cursor above an eval-c block in
emacs, press ctrl+alt+x, and there it flies. (I have also added support
for classes and a lot more, but those additions hasn't been made public
yet.)

By the way, this is the way lrdf-support is handled in snd.

Quoting:

"
EVAL-C
------

eval-c takes as arguments lisp- and C-like blocks, generates c-code from
it, and runs it.

Some reasons to use eval-c:

* Easy integration of c-code from within lisp.
  Mix C and Lisp in the same source without making it look strange.
  (hopefully)
* Use lisp-macros to generate c-code. (There is a special macro function
  called "define-c-macro" that works with eval-c)
* Generate/compile/link/run c-code on the fly.
* Some people think prefix notation is nice.
* Speed. C is faster than guile.
* Hides guile-semantic to access C-code from guile. Less need to read the
  guile manual.
* Global functions does not need to be defined at the top-level. (that is
  a good thing,
  right?)

Examples.
--------

The simplest fibonacci function:

(define-c <int> (fib ((<int> n))
                     (if (< n 2)
                         (return n)
                         (return (+ (fib (- n 1))
                                    (fib (- n 2)))))))

The define-c macro will produce the following code:

(eval-c ""
        (public
         (<int> fib (lambda ((<int> n))
                      (if (< n 2)
                          (return n)
                          (return (+ (fib (- n 1))
                                     (fib (- n 2)))))))))

The "public" macro will change the code so that it looks something like
this:

(eval-c ""
        (<int> fib (lambda ((<int> n))
                     (if (< n 2)
                         (return n)
                         (return (+ (fib (- n 1))
                                    (fib (- n 2)))))))
        (<static-SCM> fib_eval_c_helper (lambda ((<SCM> n))
                                          (return (MAKE_INTEGER (fib
(GET_INTEGER n))))))
        (run-now
         (scm_c_define_gsubr "fib" 1 0 0 fib_eval_c_helper)))

And after running the "lambda", "if" and "run-now" macros, eval-c will
produce and run the following c-code:

int fib (int n){
  if ((n < 2))
    return (n);
  else
    return ((fib ((n - 1)) + fib ((n - 2))));
}
static SCM fib_eval_c_helper (SCM n){
  return (MAKE_INTEGER (fib (GET_INTEGER (n))));
}
static void run_now_1 (){
  scm_c_define_gsubr ("fib", 1, 0, 0, fib_eval_c_helper);
}

The first function is the fibonacci generator, and the
second function is the guile-wrapper. (GET_INTEGER and
MAKE_INTEGER are just simple C macros.)
"run_now"-functions are run once when the file is loaded.

>From guile you now have a function called "fib" which takes
one argument.

Hello world looks like this:

(eval-c ""
        (run-now
         (printf (string "Hello world!\\n"))))

First argument to eval-c is a string with compiling/linking options.
Usually just "", but can be "-lsnd" or something if needed.

"

-- 
Received on Sat Jan 15 16:15:11 2005

This archive was generated by hypermail 2.1.8 : Sat Jan 15 2005 - 16:15:11 EET