; .EnTete "Le-Lisp (c) version 15.2" " " "Les appels externes"
; .EnPied "callext.ll" "I-%" " "
; .Annexe I "Les Appels Externes"
; .nr % 1
;
; .Centre "*****************************************************************"
; .Centre " Ce fichier est en lecture seule hors du projet ALE de l'INRIA. "
; .Centre " Il est maintenu par ILOG SA, 2 Avenue Gallie'ni, 94250 Gentilly "
; .Centre " (c) Le-Lisp est une marque de'pose'e de l'INRIA "
; .Centre "*****************************************************************"
; $Header: callext.ll,v 4.9 89/01/11 14:28:19 kuczynsk Exp $
(unless (>= (version) 15.2)
(error 'load 'erricf 'callext))
(defvar #:sys-package:colon 'system)
(add-feature 'callext)
(de #:system:cached-getglobal (s)
(if (null #:system:defextern-cache)
(getglobal s)
(let ((res (cons 0 0)))
(newl #:system:getglobal-cache
(cons s res))
res)))
; Toutes ces fonctions sont "autoload" dans le syste`me minimum.
(dmd defextern (nom ltype . type)
(buildextern nom
(#:system:cached-getglobal nom)
ltype
(or (car type) 'fix)))
(de buildextern (nom adr ltype type)
; de'fini une proce'dure externe
(let* (;; compteur d'arguments
(n -1)
;; liste des parametres
(lvar (mapcar (lambda (l)
(symbol ':callext
(concat "arg" (incr n))))
ltype))
;; le corps de la fct de'finie par defextern
(body `(callextern ; appel externe
(precompile ,(if (numberp adr) adr `',adr)
()
()
(eval
(kwote (#:system:cached-getglobal ',nom))) )
; numero du type de la valeur rendue
,(:conv-extern-to-ll type)
; plist (parametre1 numero-type1 ...)
,@(mapcan (lambda (type var)
(if (eq type 'external)
`((vag ,var) ,(:conv-ll-to-extern type))
`(,var ,(:conv-ll-to-extern type))))
ltype lvar))
))
(when (eq type 'external)
(setq body `(loc ,body)))
(if (and (numberp adr) (zerop adr))
(error 'defextern 'errudf nom)
`(de ,nom ,lvar ,body))) )
(de :conv-ll-to-extern (type)
;; Tous ces nume'ros sont e'galement de'crits et utilise's
;; dans llxxx.llm3 spe'cifique a` la machine utilise'e.
(selectq type
(external 0)
(fix 1)
(float 2)
(string 3)
(vector 4)
(rfix 5) ; FIX par reference (FORTRAN)
(rfloat 6) ; FLOAT par reference (FORTRAN)
(fixvector 7) ; vecteur d'entiers
(floatvector ; vecteur de flottants.
(if (eq 0.0 0.0) ; On ne sait pas faire completement
8 ; les vecteurs de flottants
(error 'defextern ; en 64bitfloats.
'errgen
"floatvector (64BITFLOATS)")))
((t) 0) ; T arre↑te les clauses!!
(t (error 'defextern 'erroob type))))
(de :conv-extern-to-ll (type)
;; Tous ces nume'ros sont e'galement de'crits et utilise's
;; dans llxxx.llm3 spe'cifique a` la machine utilise'e.
;; On ne sait pas ramener un tableau: comment connaitre sa longueur?
(selectq type
(external 0)
(fix 1)
(float 2)
(string 3)
((t) 0)
(t (error 'defextern 'errgen type))))
(unless (boundp '#:system:getglobal-cache)
(defvar #:system:getglobal-cache ()))
(unless (boundp '#:system:defextern-cache)
(defvar #:system:defextern-cache ()))
(de defextern-cache &nobind
(selectq (arg)
(0 #:system:defextern-cache)
(1
(when (and (null (arg 0))
#:system:defextern-cache)
(getglobal-flush-cache))
(setq #:system:defextern-cache (arg 0)))
(t (error 'defextern-cache 'errwna 1))))
(de getglobal-flush-cache ()
(when #:system:getglobal-cache
(let ((name-list
(mapcar (lambda (pair) (string (car pair)))
#:system:getglobal-cache))
(errors ()))
(←mgetglo name-list ())
(mapc (lambda (pair value)
(if (eq 0 value)
(newl errors (car pair))
(setq value (loc value))
(rplac (cdr pair)
(if (fixp value) 0 (car value))
(if (fixp value) value (cdr value)))))
#:system:getglobal-cache
name-list)
(setq #:system:getglobal-cache ())
(when errors
(error 'defextern 'errudf (nreverse errors))))))
(de cload (s)
(if #:system:cloadp
(:ccode (←cload (string s) (:ccode) (:ecode)))
(error 'cload
#+ #:system:foreign-language "not implemented in the system"
#- #:system:foreign-language "non implemente dans le systeme"
(system))))
(defextern ←mgetglo (t t))
#+ #:system:cloadp
(defextern ←cload (string external external) external)
; Les tests de lelisp.c :
#| en enlever en cas de test
(defextern-autoflush ())
(defextern ←cchdir (string) fix)
(defextern ←chome () string)
(defextern ←cmoinsun () fix)
(defextern ←ctest (string float fix vector) float)
(defextern-autoflush t)
(setq vect #[a b])
(←ctest "FooBar" 123.45 123 vect)
|#