; .EnTete "Le-Lisp (c) version 15.2" " " "Les Structures"
; .EnPied "defstruct.ll" "G-%" " "
; .Annexe G "Les Structures"
; .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 "*****************************************************************"
; .Centre "$Header: defstruct.ll,v 4.3 88/11/19 17:06:45 nuyens Exp $"
; Un defstruct tre`s simple, tire' de celui d'Alcyone avec :
; - l'utilisation des vecteurs type's
; - fonction d'acce`s sous forme d'EXPR qui ne consent pas
; - fonction de cre'ation : #:type:make
; - compatibilite' d'utilisation avec Ceyx (Objval et TCONS libres)
; - utilisation des P-listes des types.
(unless (>= (version) 15.2)
(error 'load 'erricf 'defstruct))
; Tous les symboles pre'ce'de's de : seront cre'e's dans le package DEFSTRUCT
(defvar #:sys-package:colon 'defstruct)
(add-feature 'defstruct)
(defvar #:system:defstruct-all-access-flag t)
; .Section "Le type STRUCTURE"
; La Pliste d'une structure contient, sous l'indicateur defstruct
; un CONS qui contient :
; - le segment de valeur d'appel a` la fonction VECTOR
; pour cre'er le segment de vecteur de ce type simple.
; - la liste des noms des champs a` la de'finition (pour la
; lecture et l'e'criture de la syntaxe #S(nom val .....) )
; P.S. les noms des champs he'rite's et leurs valeurs initiales ne sont
; pas sauvegarde's sur la P-liste.
(de structurep (x)
(if (and (vectorp x)
(getprop (typevector x) 'defstruct))
t
()))
; .Section "La fonction de de'finition de structure"
(defmacro defstruct (name . lfield)
; pose de la valeur initiale () par de'faut
(unless (variablep name)
(error 'defstruct 'errnva name))
(let ((name1 name)
(index -1)
(make (mapcar (lambda (x)
(cond ((symbolp x) ())
((or (atom x)
(not (symbolp (car x))))
(error 'defstruct 'errnaa x))
(t (cadr x))))
lfield))
(lfieldt (mapcar (lambda (x)
(if (atom x) x (car x)))
lfield)))
; C'est ca qui sera sauve sur la plist.
(setq lfield (cons make lfieldt))
(until (or (eq (packagecell name1) '||)
(null (getprop (packagecell name1) 'defstruct)))
(setq name1 (packagecell name1))
(setq make (append (car (getprop name1 'defstruct)) make))
(setq lfieldt (append (cdr (getprop name1 'defstruct))
lfieldt)))
`(exportable-definition ',name 'structure
(putprop ',name ',lfield 'defstruct)
(de ,(symbol name 'make) ()
(let ((vector (vector ,@make)))
(typevector vector ',name)
vector))
,@(mapcan
(lambda (f)
(incr index)
(when (or #:system:defstruct-all-access-flag
(memq f lfield))
(setq f (symbol name f))
`((de ,f &nobind
(#:system:structaccess ',f ,index
(arg 0)
(arg 1)
(arg)))
(when (featurep 'setf) (defsetf ,f ,f))
(when (featurep 'compiler)
(defmacro-open
,f (struct . valeur)
(ifn valeur
`(vref ,struct ,,index)
`(vset ,struct
,,index
,(car valeur))))
))))
lfieldt)
)))
; .Section "La fonction de cre'ation ge'ne'rique"
(de new (type)
(if (getprop type 'defstruct)
(apply (symbol type 'make) ())
(error 'new 'errstc type)))