MKCL icon indicating copy to clipboard operation
MKCL copied to clipboard

`walker:macroexpand-all` doesn't macroexpand in some cases

Open Gleefre opened this issue 1 year ago • 0 comments

Description

walker:macroexpand-all doesn't expand macros in three cases: if it is a global symbol-macro, a local symbol-macro in the environment passed as a second argument, or a local macro in the form to be expanded.

"Mega" test

Here is a test for 6 possible cases where macro expansion should happen:

(require :walker)

;; utility macro
(defmacro at-compile-time ((&optional env) &body body)
  (let ((capture (gensym)))
    `(macrolet ((,capture (,@(when env `(&environment ,env)))
                  ,@body))
       (,capture))))

(defmacro NO-1 () ''YES-1)
(define-symbol-macro NO-4 'YES-4)

(macrolet ((NO-3 () ''YES-3))
  (symbol-macrolet ((NO-6 'YES-6))
    (at-compile-time (env)
      `',(walker:macroexpand-all
          '(macrolet ((NO-2 () ''YES-2))
             (symbol-macrolet ((NO-5 'YES-5))
               (values (NO-1) (NO-2) (NO-3) NO-4 NO-5 NO-6)))
          env))))

Result:

(MACROLET ((NO-2 ()
             ''YES-2))
  (SYMBOL-MACROLET ((NO-5 'YES-5))
    (VALUES 'YES-1 (NO-2) 'YES-3 NO-4 'YES-5 NO-6)))

Expected:

(MACROLET ((NO-2 ()
             ''YES-2))
  (SYMBOL-MACROLET ((NO-5 'YES-5))
    (VALUES 'YES-1 'YES-2 'YES-3 'YES-5 'YES-5 'YES-6)))

Smaller tests for each case:

(require :walker)
(define-symbol-macro macroexpand-all-test-1 'expanded)
(walker:macroexpand-all 'macroexpand-all-test-1)
; => MACROEXPAND-ALL-TEST-1
(require :walker)
(symbol-macrolet ((macroexpand-all-test-2 'expanded))
  (macrolet ((thunk (&environment env)
               `',(walker:macroexpand-all
                   'macroexpand-all-test-2
                   env)))
    (thunk)))
; => MACROEXPAND-ALL-TEST-2
(require :walker)
(walker:macroexpand-all
 '(macrolet ((macroexpand-all-test-3 () ''expanded))
    (macroexpand-all-test-3)))
; => (MACROLET ((MACROEXPAND-ALL-TEST-3 ()
;                 ''EXPANDED))
;      (MACROEXPAND-ALL-TEST-3))

In each case the symbol macroexpand-all-test-x should've been macroexpanded.

Version

Tested on MKCL 1.1.11.206 (current head):

(lisp-implementation-version)  ; => "1.1.11.206-b414811"

Additional information

This also affects ECL, see https://gitlab.com/embeddable-common-lisp/ecl/-/issues/722.

Also see this table (second table) testing macroexpand-all across different implementations: https://plaster.tymoon.eu/view/4637.

Gleefre avatar Nov 01 '24 18:11 Gleefre