Embeddable Common-Lisp

Content from 2005-10

Windows application

posted on 2005-10

Michael Goffioul has updated his sample text editor. It now uses ECL's dynamic FFI to access the Windows API and can run either compiled or interpreted. Furthermore, by embedding Scintilla's component (http://www.scintilla.org), the editor can perform syntax highlighting of Lisp code.

A screenshot is here: http://sourceforge.net/project/screenshots.php?group_id=30035

With higher resolution also available here: http://ecls.sf.net/screenshot.png

Dynamic FFI

posted on 2005-10

ECL's unstable version (in CVS) now contains means both to call C functions and to export functions to the C world (callbacks). Furthermore, this project, initiated by M. Goffioul, has led to an implementation that, at least on the Intel platform, does not rely on the C compiler, but on assembler code generated run time. We hope to port this to the remaining architectures: PPC, Sparc, x86_64

If you want to test it, save the code below in a file called "example.lsp" and load it in the interpreter (if on x86/Windows,Linux,FreeBSD) or compile it and load it (if on other platforms).

The output should look as follows: the first column is the input value, the second and fourth column are the output of either a callback or a C function (in this case "sin"). Other columns are provided to compare accuracy of the result.

Value 1+ (cback) lisp sin(cfun) lisp

     0        1.0        1.0        0.0        0.0
     1        2.0        2.0 .841470985 0.84147096
     2        3.0        3.0 .909297427  0.9092974
     3        4.0        4.0 .141120008    0.14112
     4        5.0        5.0 -0.7568025 -0.7568025
     5        6.0        6.0 -.95892427 -0.9589243
     6        7.0        7.0 -0.2794155 -0.2794155
     7        8.0        8.0 .656986599  0.6569866
     8        9.0        9.0 .989358247 0.98935825
     9       10.0       10.0 .412118485  0.4121185

;; Notice that the following example will work on all platforms if compiled ;; as in ;; (COMPILE-FILE "example.lisp") ;; (LOAD-FILE "example") ;; ;; However, on the x86 platform (i.e. Intel running Linux, FreeBSD, Windows, ;; etc on 32 bit modes), this example also works when loaded from the ;; interpreter. In this case, assembly code is built at run-time and there ;; is no need to have a C compiler around. Ports to other architectures are ;; being developed and any kind of help is welcome. ;;

;; ;; This is a "callback", i.e. a function that can be called from the C world. ;; We can retreive a UFFI pointer to this function using #'FFI:CALLBACK, as ;; shown below. ;; (ffi:defcallback increment :double ((x :double)) (1+ x) )

;; ;; This is a foreign function, i.e. a C function that can be called from the ;; lisp world. Here we do not need to handle pointers: a lisp function called ;; C-SIN is created that does the job of translating arguments for us. The ;; syntax here is pure UFFI. ;; (ffi:def-function ("sin" C-sin) ((x :double)) :returning :double :module :default)

(format t "Value 1+ (cback) lisp sin(cfun) lisp ~%") (format t "=====================================================~%")

(dotimes (i 10) (format t "~10D ~10f ~10f ~10f ~10f~%" i (si::call-cfun (ffi:callback 'increment) :double '(:double) (list i)) (1+ i) (C-sin i) (sin i)))

From ASDF to shared libraries

posted on 2005-10

Michael Goffioul has contributed a wonderful hack that allows one to build a single FASL file, a shared library or a standalone executable out of a ASDF system definition. The transcription below shows how it works for the CL-PPCRE library. As usual this is only available in the CVS version of ECL.

~/src/lisp$ cd cl-ppcre-1.2.11/ ~/src/lisp/cl-ppcre-1.2.11$ ecl ECL (Embeddable Common-Lisp) 0.9g Copyright (C) 1984 Taiichi Yuasa and Masami Hagiya Copyright (C) 1993 Giuseppe Attardi Copyright (C) 2000 Juan J. Garcia-Ripoll ECL is free software, and you are welcome to redistribute it under certain conditions; see file 'Copyright' for details. Type :h for Help. Top level. > (require 'asdf) ;;; Loading #P"/home/jlr/lib/ecl/asdf.fas" ... > (load "cl-ppcre.asd") ;;; Loading "cl-ppcre.asd" "cl-ppcre.asd" > (use-package "ASDF") T > (make-build :cl-ppcre :type :fasl) ;;; Loading #P"/home/jlr/lib/ecl/cmp.fas" ;;; Loading #P"/home/jlr/lib/ecl/sysfun.lsp" ;;; Loading "/home/jlr/src/lisp/cl-ppcre-1.2.11/packages.lisp" ;;; Loading "/home/jlr/src/lisp/cl-ppcre-1.2.11/specials.lisp" [...] > (load "cl-ppcre.fas") ;;; Loading "cl-ppcre.fas" [...] "cl-ppcre.fas" > (load "ppcre-tests") ;;; Loading #P"ppcre-tests.lisp"

P"ppcre-tests.lisp"

> (cl-ppcre-test:test) .......... .......... .......... .......... .......... .......... ...... 662 ("a" =~ /((a))/): \2: expected NIL but got "a" .... ......... 790 ("babc" =~ /^(b*|ba){1,2}bc/): \1: expected "" but got "ba" . .......... .......... .......... .......... .......... .......... ... 1439 ("dbaacb" =~ /(?<!(c|d))[ab]/): \1: expected NIL but got "d" ....... .......... ..

The errors are expected, as mentioned in the CL-PPCRE documentation