2010-04-24 8 views
8

Ni siquiera conozco la terminología adecuada para esta sintaxis de lisp, por lo que no sé si las palabras que estoy usando para formular la pregunta tienen sentido. Pero la pregunta tiene sentido, estoy seguro.emacs: ¿cómo uso edebug en el código que está definido en una macro?

Déjenme mostrarles. cc-mode (cc-fonts.el) tiene cosas llamadas "matchers" que son bits de código que se ejecutan para decidir cómo crear una región de código. Eso suena bastante simple, pero el código de coincidencia está en una forma que no entiendo completamente, con signos de interrogación y comas-atsign y solo coma, etc., y además está incrustado en un c-lang-defcost, que a su vez es un macro. No sé cómo llamar todo eso, pero quiero ejecutar edebug en ese código.

Look:

(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))))))) 

estoy leyendo sobre la sintaxis Lisp para averiguar cuáles son esas cosas y cómo llamarlos, pero aparte de eso, ¿cómo puedo ejecutar edebug en el código que sigue al comentario que dice ;; Fontify the identifiers inside enum lists.?

Sé cómo ejecutar edebug en un defun - solo invoque edebug-defun dentro de la definición de la función, y listo. ¿Hay algo que deba hacer para eliminar las formas de código del emparejador cc-mode?

¿Qué hace def-edebug-spec hacer, y lo usaría aquí? ¿Si es así, cómo?

Respuesta

4

Según (elisp)Top > Debugging > Edebug > Edebug and Macros tiene que decirle a Edebug cómo depurar una macro definiéndola con debug declaraciones o usando def-edebug-spec. Esto le dice qué parámetros deben evaluarse y cuáles no. Entonces se puede hacer. De hecho, parece que c-lang-defconst ya se ha ajustado para edebug. Aquí está la definición en caso de que estuviera interesado:

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

Sin embargo, si lo que desea es ver lo que el cuerpo se evalúa como, entonces la manera de hacerlo es utilizar algo como macro-expand-last-sexp siguiente para ver el resultado. Coloque el cursor después de la sexp que desea expandir (como lo haría para C-x C-e) y ejecute M-x macro-expand-last-sexp RET. Esto le mostrará a qué se expande. Puede encontrar problemas si intenta expandir algo como ,(....), por lo que puede tener que copiar ese sexp en otro lugar y eliminar , o ,@.

(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))))) 

Supongo que depende exactamente de lo que intenta hacer.

+0

Ha pasado un tiempo, pero creo que edebug maneja la macro backtick ('), y sus constructos especiales para enderezar (, y, @) correctamente. No hay una forma de usar edebug en solo una subexpresión dentro de una definición. En cambio, debes instrumentar toda la expresión defun o top-level. – dlaliberte

4

Utilice macroexpand o macroexpand-all para convertirlo en código libre de macros y depurar como de costumbre?

acentos abiertos & co pueden ser mejor ilustrados por un ejemplo:

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

A backtick (o backquote `) es similar a una cotización (') en que evita la evaluación, salvo su efecto se puede deshacer selectivamente con una coma (,); y ,@ es como ,, excepto que su argumento, que debe ser una lista, se empalma en la lista resultante.

Cuestiones relacionadas