Plaster
New
List
Login
common-lisp
default
anonymous
2023.10.12 00:20:22
;;;; a recursive macro that modifies its own definition -- @phoe ;;;; What I want (with-inner-up ...) ; => (macrolet ((#:up0 () '(1+ (global-up))) (up () '(#:up0))) ...) (with-inner-up (with-inner-up ...) ; => (macrolet ((#:up0 () '(1+ (global-up))) (up () '(#:up0))) (macrolet ((#:up1 () '(1+ (#:up0))) (up () '(#:up1)))) ...) ;;;; Trick implementation (defmacro global-up () 0) (defmacro up () '(global-up)) (defun expand-inner-up (outer-name body) (let ((inner-up (gensym "INNER-UP"))) `(macrolet ((,inner-up () '(1+ (,outer-name))) (up () '(,inner-up)) (with-inner-up (&body body) (expand-inner-up ',inner-up body))) ,@body))) (defmacro with-inner-up (&body body) (expand-inner-up 'global-up body)) ;;;; Local constant variable (kinda) with macros (defmacro %place (var) var) (defmacro place (var) '(%place var)) (defun expand-my-let (outer-place bindings body) (let ((inner-place (gensym "%PLACE"))) `(macrolet ((,inner-place (var) (case var ,@(loop for (var binding) in bindings collect `(,var ',binding)) (t `(,',outer-place ,var)))) (place (var) `(,',inner-place ,var)) (my-let (bindings &body body) (expand-my-let ',inner-place bindings body))) ,@body))) (defmacro my-let (((var binding) &rest bindings) &body body) (expand-my-let '%place `((,var ,binding) ,@bindings) body))
Raw
Annotate
Repaste
Edit