[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.lisp

Strange behavior of SBCL code walker

Antsan

8/18/2015 4:41:00 PM

I was looking into this article
http://christophe.rhodes.io/notes/blog/posts/2014/naive_vs_proper_cod...
and tried to fix a bug in defmacro!, where it doesn't destructure macro lambda
lists properly and tried something like this:

(let ((o!symbols '()))
(sb-walker:walk-form args nil
(lambda (subform context env)
(declare (ignore context env))
(typecase subform
(symbol
(when (o!sym? subform)
(pushnew subform o!symbols))
subform)
(t subform))))
; do stuff with o!symbols - if you want to see what happens, just copy
; and wrap in something that supplies ARGS
o!symbols)

Here's my implementation of O!SYM?:
(defun o!sym? (obj)
(and (symbolp obj)
(let ((n (symbol-name obj)))
(and (> (length n)
2)
(string= (subseq n 0 2)
"O!")))))

Now, this did not work as I expected when given an arglist like
'(o!a o!b (o!c o!d))
The only o!symbols found where O!B and O!D.
Of course I immediately checked whether defmacro/g! actually worked as intended,
as I distinctly remember g!symbols being used for local function names.
To my surprise, these worked.

So, supply something like
'`(,o!a ,o!b (,o!c ,o!d))
and the walker finds all the o!symbols as intended.

As lambda lists don't contain backquote syntax, I finally decided that it would
be fine to use FLATTEN for this purpose.
I have an idea of why it works that way, but its kind of hazy. Something about
how the o!*-symbols in '`(,o!a ,o!b (,o!c ,o!d)) are actually arguments to
the sb-impl:backq-* forms and thus recognized?