Sujet : Re: challenge: insert a literal reader conditional
De : enometh (at) *nospam* meer.net (Madhu)
Groupes : comp.lang.lispDate : 14. Apr 2025, 06:06:44
Autres entêtes
Organisation : Motzarella
Message-ID : <m3ikn7jpqz.fsf@leonis4.robolove.meer.net>
References : 1
* I, Madhu <
m3r01vjy4u.fsf@leonis4.robolove.meer.net> :
Wrote on Mon, 14 Apr 2025 07:35:37 +0530:
Anyone know of a hack to insert literal reader conditionals in generated
code?
>
(setq $a '(+ 1 2 3))
>
assume I want to dump $a to a file, but I want the file to contain the
text
>
"(+ 1 2 3 #+foo 4)"
>
is it possible to do this at all without string-replace on the generated
output file?
>
I'm pretty sure it is not possible theoretically, but maybe there is
some insane hack.
>
asdf (and now mk-defsystem) solves this by using :IF-FEATURE constructs
that handle some features at read time.
so one can write
>
(:FILE "x86_64-pc-linux-gnu" :IF-FEATURE (:AND :X86-64 :LINUX))
and defsystem will expand this to (:file "x86_64-pc-linux-gnu")
when processing the form if the features are present and omit the form
if they are not.
Answering myself in the best form a crude solution (without bells and
whistles to handle #+(and) #+(or) combinaions of features) follows
directly from the above mentioned :if-feature facility. for the limited
example above
(defclass feature-hack ()
((feature :initarg :feature :type keyword)
(if-feature-form :initarg :if-feature)
(if-not-feature-form :initarg :if-not-feature)))
(defmethod print-object ((obj feature-hack) stream)
(destructuring-bind (feature-boundp if-feature-form-boundp if-not-feature-form-boundp)
(mapcar (lambda (x) (slot-boundp obj x))
'(feature if-feature-form if-not-feature-form))
(if (or (not feature-boundp)
(and (not if-feature-form-boundp)
(not if-not-feature-form-boundp)))
;; comments welcome:
(print-unreadable-object (obj stream :type t :identity t))
(with-slots (feature if-feature-form if-not-feature-form) obj
(check-type feature keyword)
(when if-feature-form-boundp
(format stream "#+:~A ~S" feature if-feature-form))
(when if-not-feature-form-boundp
(format stream "~:[~; ~]#-:~A ~S"
if-feature-form-boundp feature if-not-feature-form))))))
(setq $a `(+ 1 2 3
,(make-instance 'feature-hack :feature :foo :if-feature 4)))
(with-output-to-string (s)
(let ((*print-readably* t))
(write $a :stream s)))
;; => "(+ 1 2 3 #+:FOO 4)"