2013-07-06 130 views
1

我想知道,如果有方法檢查repl中定義和加載宏的源代碼嗎?檢查通用lisp宏源

宏觀展開-1的排序,但沒有展開。

+0

您的意思是說,您正在尋找一種方式,從使用宏,例如'with-resource',例如'(with-resource(...)...)',去到相應的定義'(defmacro with-resource(...)...)'? –

+0

是的,我的意思就是這個。 –

回答

5

可以使用macro-function獲得宏定義:

> (defmacro foo (x) `(* ,x ,x)) 
FOO 
> (macro-function 'foo) 
#<FUNCTION FOO (SYSTEM::<MACRO-FORM> SYSTEM::<ENV-ARG>) (DECLARE (CONS SYSTEM::<MACRO-FORM>)) 
    (DECLARE (IGNORE SYSTEM::<ENV-ARG>)) 
    (IF (NOT (SYSTEM::LIST-LENGTH-IN-BOUNDS-P SYSTEM::<MACRO-FORM> 2 2 NIL)) 
    (SYSTEM::MACRO-CALL-ERROR SYSTEM::<MACRO-FORM>) 
    (LET* ((X (CADR SYSTEM::<MACRO-FORM>))) (BLOCK FOO `(* ,X ,X))))> 

然而,對於大多數宏(尤其是系統的)代碼將被編譯:

> (macro-function 'with-open-file) 
#<COMPILED-FUNCTION WITH-OPEN-FILE> 

所以,要了解它如何作品,你必須吧:

> (disassemble (macro-function 'with-open-file)) 

Disassembly of function WITH-OPEN-FILE 
(CONST 0) = 2 
(CONST 1) = SYSTEM::LIST-LENGTH-IN-BOUNDS-P 
(CONST 2) = SYSTEM::MACRO-CALL-ERROR 
(CONST 3) = 1 
(CONST 4) = SOURCE-PROGRAM-ERROR 
(CONST 5) = :FORM 
(CONST 6) = :DETAIL 
(CONST 7) = "~S: ~S does not match lambda list element ~:S" 
(CONST 8) = SYSTEM::TEXT 
(CONST 9) = WITH-OPEN-FILE 
(CONST 10) = (STREAM &REST SYSTEM::OPTIONS) 
(CONST 11) = LET 
(CONST 12) = OPEN 
(CONST 13) = DECLARE 
(CONST 14) = SYSTEM::READ-ONLY 
(CONST 15) = UNWIND-PROTECT 
(CONST 16) = MULTIPLE-VALUE-PROG1 
(CONST 17) = PROGN 
(CONST 18) = WHEN 
(CONST 19) = CLOSE 
(CONST 20) = (:ABORT T) 
2 required arguments 
0 optional arguments 
No rest parameter 
No keyword parameters 
78 byte-code instructions: 
0  (LOAD&PUSH 2) 
1  (CONST&PUSH 0)      ; 2 
2  (CONST&PUSH 0)      ; 2 
3  (T&PUSH) 
4  (CALL 4 1)       ; SYSTEM::LIST-LENGTH-IN-BOUNDS-P 
7  (JMPIFNOT L85) 
10 (LOAD 2) 
11 (CDR) 
12 (CAR&PUSH) 
13 (LOAD&PUSH 0) 
14 (CONST&PUSH 3)      ; 1 
15 (CONST&PUSH 3)      ; 1 
16 (T&PUSH) 
17 (CALL 4 1)       ; SYSTEM::LIST-LENGTH-IN-BOUNDS-P 
20 (JMPIFNOT L90) 
23 (LOAD&PUSH 0) 
24 (LOAD&CAR&PUSH 0) 
26 (LOAD&CDR&PUSH 1) 
28 (LOAD 6) 
29 (CDR) 
30 (CDR&PUSH) 
31 (LOAD&PUSH 0) 
32 (PUSH-UNBOUND 1) 
34 (CALLS1 105)      ; SYSTEM::PARSE-BODY 
36 (NV-TO-STACK 2) 
38 (CONST&PUSH 11)      ; LET 
39 (LOAD&PUSH 5) 
40 (CONST&PUSH 12)      ; OPEN 
41 (LOAD 6) 
42 (CONS&PUSH) 
43 (LIST&PUSH 2) 
45 (LIST&PUSH 1) 
47 (CONST&PUSH 13)      ; DECLARE 
48 (CONST&PUSH 14)      ; SYSTEM::READ-ONLY 
49 (LOAD&PUSH 8) 
50 (LIST&PUSH 2) 
52 (LOAD 4) 
53 (CONS) 
54 (CONS&PUSH) 
55 (CONST&PUSH 15)      ; UNWIND-PROTECT 
56 (CONST&PUSH 16)      ; MULTIPLE-VALUE-PROG1 
57 (CONST&PUSH 17)      ; PROGN 
58 (LOAD 7) 
59 (CONS&PUSH) 
60 (CONST&PUSH 18)      ; WHEN 
61 (LOAD&PUSH 11) 
62 (CONST&PUSH 19)      ; CLOSE 
63 (LOAD&PUSH 13) 
64 (LIST&PUSH 2) 
66 (LIST&PUSH 3) 
68 (LIST&PUSH 3) 
70 (CONST&PUSH 18)      ; WHEN 
71 (LOAD&PUSH 10) 
72 (CONST&PUSH 19)      ; CLOSE 
73 (LOAD&PUSH 12) 
74 (CONST 20)       ; (:ABORT T) 
75 (CONS) 
76 (CONS&PUSH) 
77 (LIST&PUSH 3) 
79 (LIST&PUSH 3) 
81 (LIST 4) 
83 (SKIP&RET 10) 
85 L85 
85 (LOAD&PUSH 2) 
86 (CALL1 2)       ; SYSTEM::MACRO-CALL-ERROR 
88 (SKIP&RET 3) 
90 L90 
90 (CONST&PUSH 4)      ; SOURCE-PROGRAM-ERROR 
91 (CONST&PUSH 5)      ; :FORM 
92 (LOAD&PUSH 5) 
93 (CONST&PUSH 6)      ; :DETAIL 
94 (LOAD&PUSH 4) 
95 (CONST&PUSH 7)      ; "~S: ~S does not match lambda list element ~:S" 
96 (CALL1&PUSH 8)      ; SYSTEM::TEXT 
98 (CONST&PUSH 9)      ; WITH-OPEN-FILE 
99 (LOAD&PUSH 7) 
100 (CONST&PUSH 10)      ; (STREAM &REST SYSTEM::OPTIONS) 
101 (CALLSR 7 31)      ; SYSTEM::ERROR-OF-TYPE 

這是pro對新手來說,這並不是很有啓發性。

+0

哦,我不知道宏可以編譯,出於某種原因。謝謝。 –