Skip to content

Instantly share code, notes, and snippets.

@ha2ne2
Last active December 8, 2015 05:31
Show Gist options
  • Save ha2ne2/5d988fe74e38e0276e09 to your computer and use it in GitHub Desktop.
Save ha2ne2/5d988fe74e38e0276e09 to your computer and use it in GitHub Desktop.
#+sbcl
(eval-when (:compile-toplevel :execute)
(handler-case
(progn
(sb-ext:assert-version->= 1 2 2)
(setq *features* (remove 'old-sbcl *features*)))
(error ()
(pushnew 'old-sbcl *features*))))
(defun flatten (x)
(labels ((rec (x acc)
(cond ((null x) acc)
#+(and sbcl (not old-sbcl))
((typep x 'sb-impl::comma) (rec (sb-impl::comma-expr x) acc))
((atom x) (cons x acc))
(t (rec (car x) (rec (cdr x) acc))))))
(rec x nil)))
(defun g!-symbol-p (s)
(and (symbolp s)
(> (length (symbol-name s)) 2)
(string= (symbol-name s)
"G!"
:start1 0
:end1 2)))
(defmacro defmacro/g! (name args &rest body)
(let ((syms (remove-duplicates
(remove-if-not #'g!-symbol-p
(flatten body)))))
`(defmacro ,name ,args
(let ,(mapcar
(lambda (s)
`(,s (gensym ,(subseq
(symbol-name s)
2))))
syms)
,@body))))
(defun o!-symbol-p (s)
(and (symbolp s)
(> (length (symbol-name s)) 2)
(string= (symbol-name s)
"O!"
:start1 0
:end1 2)))
(defun o!-symbol-to-g!-symbol (s)
(symb "G!" (subseq (symbol-name s) 2)))
(defmacro defmacro! (name args &rest body)
(let* ((os (remove-if-not #'o!-symbol-p args))
(gs (mapcar #'o!-symbol-to-g!-symbol os)))
`(defmacro/g! ,name ,args
`(let ,(mapcar #'list (list ,@gs) (list ,@os))
,(progn ,@body)))))
(defmacro! clj-loop (letargs &rest body)
(let ((gs (loop for i in letargs collect (gensym))))
`(macrolet
((recur ,gs
`(progn
(psetq ,@(apply #'nconc
(mapcar #'list ',(mapcar #'car letargs) (list ,@gs))))
(go ,',g!recur))))
(block ,g!block
(let* ,letargs
(tagbody ,g!recur
(return-from ,g!block
(progn ,@body))))))))
(clj-loop ((a 1) (b 2))
(if (< a 10)
(recur (1+ a) (* 2 b)))
(list a b))
;=> (10 1024)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment