Simplifying importing with pointer-pointer return.
[rrq/lsp-utils.git] / lsp-misc / define-import.lsp
1
2 ;; (import-define ...) is a combination of an import clause and a
3 ;; define clause so as to set up a "raw" import with a call wrapper.
4 ;; 
5 ;
6 ; (context 'ALSA)
7 ; (define-import PCM LIB
8 ;    "snd_pcm_open" "int"
9 ;    "void*" PCM  ; "void*" ; snd_pcm_t **pcmp [output]
10 ;    "char*" NAME   ; const char *name
11 ;    "int"   STREAM ; snd_pcm_stream_t stream
12 ;    "int"   MODE   ; int mode
13 ;    ))
14
15 (define-macro (define-import DATA LIB)
16   ;; Make a raw import
17   (println (history true))
18   (letn ((ARGL (transpose (explode (2 (args)) 2)))
19          (HERE (prefix (last (ARGL 1))))
20          (RAW  (context (sym (string (println (term HERE)) ".raw"))))
21          (NAME (sym (args 0)))
22          (ARGS (ARGL 1))
23          (FN (cons (sym (args 0) HERE) (filter (fn (x) (!= DATA x)) ARGS)))
24          (LIB (eval LIB))
25          (IMP (apply import (filter string? (cons LIB (args)))))
26          )
27     (println (list 'FN FN))
28     (if DATA
29         (letex ((FN FN)
30                 (CALL (cons IMP ARGS))
31                 (DATA DATA))
32           (define FN
33             (let ((DATA (pack "Lu" 0)))
34               (when (>= CALL)
35                 ((unpack "Lu" DATA) 0)))))
36       (letex ((FN FN) (CALL (cons IMP ARGS)))
37         (define FN CALL))
38       )))
39 (global 'define-import)