2008/10/02

[Common Lisp] with-[]

わだばLisperになる(g000001)さんの添字的symbol-macroletがおもしろかったので、symbol-macrolet を使わないバージョンを書いてみた。Let On Lambda に出てきそうなやつ。

残念ながら h[foo] としてシンボル foo 自体をキーとすることができない。foo の値がキーになる。あと、setf もできない。

(require :cl-ppcre)

(defgeneric access-[] (obj index)
(:method ((obj list) index)
(nth index obj))
(:method ((obj sequence) index)
(elt obj index))
(:method ((obj hash-table) index)
(gethash index obj)))

(defmacro with-[] (&body body)
(labels (([]-p (x)
(when (symbolp x)
(cl-ppcre:register-groups-bind (symbol index)
("(.+)\\[(.+)\\]$" (symbol-name x))
(values symbol index))))
(map-form (form)
(cond ((atom form)
(multiple-value-bind (symbol index) ([]-p form)
(if symbol
`(access-[] ,(find-symbol symbol)
,(read-from-string index))
form)))
(t
(cons (map-form (car form))
(map-form (cdr form)))))))
`(progn ,@(map-form body))))

(with-[]
(let ((n 2)
(l '(1 2 3))
(s "hello")
(h (make-hash-table)))
(setf (gethash n h) "ハッシュ")
(list l[n] s[n] h[n])))
;; => (3 #\l "ハッシュ")

#|
h[foo] とかして シンボル foo をキーにするのはできない。
setf もできない。
|#

0 件のコメント: