emacs: как мне использовать edebug для кода, определенного в макросе? - PullRequest
8 голосов
/ 24 апреля 2010

Я даже не знаю правильной терминологии для этого синтаксиса lisp, поэтому я не знаю, имеют ли смысл слова, которые я использую, чтобы задать вопрос. Но вопрос имеет смысл, я уверен.

Итак, позвольте мне показать вам. В cc-mode (cc-fonts.el) есть вещи, называемые «сопоставителями», которые представляют собой фрагменты кода, которые выполняются для определения способа обозначения области кода. Это звучит достаточно просто, но код сопоставления находится в форме, которую я не совсем понимаю, с обратными чертами и запятыми, просто запятыми и так далее, и, кроме того, он встроен в c-lang-defcost, который сам по себе является макро. Я не знаю, как все это назвать, но я хочу запустить edebug для этого кода.

Смотри:

 (c-lang-defconst c-basic-matchers-after
   "Font lock matchers for various things that should be fontified after
 generic casts and declarations are fontified.  Used on level 2 and
 higher."

   t `(;; Fontify the identifiers inside enum lists.  (The enum type
       ;; name is handled by `c-simple-decl-matchers' or
       ;; `c-complex-decl-matchers' below.
       ,@(when (c-lang-const c-brace-id-list-kwds)
           `((,(c-make-font-lock-search-function
                (concat
                 "\\<\\("
                 (c-make-keywords-re nil (c-lang-const c-brace-id-list-kwds))
                 "\\)\\>"
                 ;; Disallow various common punctuation chars that can't come
                 ;; before the '{' of the enum list, to avoid searching too far.
                 "[^\]\[{}();,/#=]*"
                 "{")
                '((c-font-lock-declarators limit t nil)
                  (save-match-data
                    (goto-char (match-end 0))
                    (c-put-char-property (1- (point)) 'c-type
                                         'c-decl-id-start)
                    (c-forward-syntactic-ws))
                  (goto-char (match-end 0)))))))

Я читаю синтаксис lisp, чтобы выяснить, что это за вещи и как их называть, но кроме этого, как я могу запустить edebug для кода, следующего за комментарием, который читает ;; Fontify the identifiers inside enum lists.?

Я знаю, как запустить edebug при defun - просто вызовите edebug-defun в определении функции, и я ухожу. Есть ли что-то, что мне нужно сделать, чтобы edebug формы кода соответствия cc-mode?

Что делает def-edebug-spec, и буду ли я использовать это здесь? Если так, то как?

Ответы [ 2 ]

4 голосов
/ 02 мая 2010

Согласно (elisp)Top > Debugging > Edebug > Edebug and Macros вы должны указать Edebug, как отлаживать макрос, определив его с помощью операторов debug или с помощью def-edebug-spec. Это говорит о том, какие параметры должны быть оценены, а какие нет. Так что это может быть сделано. На самом деле это выглядит так, как будто c-lang-defconst уже установлено для edebug. Вот определение, если вас заинтересовало:

(def-edebug-spec c-lang-defconst
  (&define name [&optional stringp] [&rest sexp def-form]))

Однако, если вы просто хотите увидеть, что оценивает тело, то для этого нужно использовать что-то вроде macro-expand-last-sexp ниже, чтобы увидеть результат. Поместите курсор после развернутого секса (как для C-x C-e) и запустите M-x macro-expand-last-sexp RET. Это покажет вам, к чему это расширяется. Вы можете столкнуться с проблемами, если попытаетесь расширить что-то вроде ,(....), поэтому вам, возможно, придется скопировать этот sexp в другое место и удалить , или ,@.

(defun macro-expand-last-sexp (p)
  "Macro expand the previous sexp.  With a prefix argument
insert the result into the current buffer and pretty print it."
  (interactive "P")
  (let*
      ((sexp (preceding-sexp))
       (expanded (macroexpand sexp)))
    (cond ((eq sexp expanded)
           (message "No changes were found when macro expanding"))
          (p
           (insert (format "%S" expanded))
           (save-excursion
             (backward-sexp)
             (indent-pp-sexp 1)
             (indent-pp-sexp)))
          (t
           (message "%S" expanded)))))

Полагаю, это зависит от того, что именно вы пытаетесь сделать.

4 голосов
/ 01 мая 2010

Используйте macroexpand или macroexpand-all, чтобы превратить его в код без макросов и отладить как обычно?

Backticks & co лучше всего проиллюстрировать на примере:

(let ((a 1)
      (b (list 2 3)))
  `(a ,a ,b   ,@b))
-> (a  1 (2 3) 2 3)

Abacktick (или обратная кавычка `) аналогична кавычке (') в том, что она препятствует оценке, за исключением того, что ее эффект можно выборочно отменить запятой (,);и ,@ похож на ,, за исключением того, что его аргумент, который должен быть списком, включается в результирующий список.

...