40 lines
1.1 KiB
Common Lisp
40 lines
1.1 KiB
Common Lisp
(defmacro array (length)
|
|
(let* ((this (gensym))
|
|
(index-prefix (fuse this 'index))
|
|
(indices (create-indices length))
|
|
(index-bindings (map (lambda (i) (list (fuse index-prefix i))) indices)))
|
|
|
|
`(let ,index-bindings
|
|
(setq ,this
|
|
(dlambda
|
|
(:get (i)
|
|
(eval (fuse ',index-prefix i)))
|
|
|
|
(:set (i value)
|
|
(if (< i ,length)
|
|
(set (fuse ',index-prefix i) value)))
|
|
|
|
(:length ()
|
|
,length)
|
|
|
|
(t ()
|
|
((lambda (indices accumulator)
|
|
(if (null? indices)
|
|
accumulator
|
|
(recur
|
|
(rest indices)
|
|
(cons
|
|
(list (first indices) (call ,this :get (first indices)))
|
|
accumulator))))
|
|
(reverse ',indices)
|
|
nil)))))))
|
|
|
|
|
|
(defun create-indices (length)
|
|
(create-indices-tail (- length 1) ()))
|
|
|
|
(defun create-indices-tail (index accumulator)
|
|
(if (< index 0)
|
|
accumulator
|
|
(recur (- index 1) (cons index accumulator))))
|