Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-core/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Macros 在公共Lisp中获取宏的堆栈跟踪模拟_Macros_Common Lisp_Stack Trace_Trace - Fatal编程技术网

Macros 在公共Lisp中获取宏的堆栈跟踪模拟

Macros 在公共Lisp中获取宏的堆栈跟踪模拟,macros,common-lisp,stack-trace,trace,Macros,Common Lisp,Stack Trace,Trace,我可能是在要求不可能的事情,但我还是想知道 是否可以获得宏的堆栈跟踪模拟?也就是说,如果在某个函数中设置了断点,宏堆栈跟踪将列出所有宏(可能包括它们的输入),这些宏经过宏扩展以在代码中达到该级别 据我所知,这目前是不可能的,但这可能是由于我的理解肤浅。Allegro或SBCL是否允许或跟踪此类信息?这似乎对调试宏非常有用 任何帮助或建议都将不胜感激。因为SBCL意味着所有代码都是自动编译的(而不是“解释的”)。对宏的调用作为编译的一部分进行了扩展,因此丢失了某个宏调用的事实 (defmacro

我可能是在要求不可能的事情,但我还是想知道

是否可以获得宏的堆栈跟踪模拟?也就是说,如果在某个函数中设置了断点,宏堆栈跟踪将列出所有宏(可能包括它们的输入),这些宏经过宏扩展以在代码中达到该级别

据我所知,这目前是不可能的,但这可能是由于我的理解肤浅。Allegro或SBCL是否允许或跟踪此类信息?这似乎对调试宏非常有用

任何帮助或建议都将不胜感激。

因为SBCL意味着所有代码都是自动编译的(而不是“解释的”)。对宏的调用作为编译的一部分进行了扩展,因此丢失了某个宏调用的事实

(defmacro m (n)
   `(/ 10 ,n))

(defun foo (x) (m x))
SBCL:

需要更多详细的选项,这显示了形式
(block foo(mx))

当您
(编译'foo)
时,宏调用将被展开(如SBCL),不再显示在回溯中(但Allegro的可能会有所帮助)

通常,在定义宏时,为了帮助调试,请尝试扩展到函数调用,而不是大型代码体。例如,代替:

(defmacro with-foo ((var-x var-y thing) &body body)
   `(let ((,var-x (..derive from ,thing ..))
          (,var-y (..derive from ,thing ..)))
       ,@body))
我会这样写:

(defmacro with-foo ((var-x var-y thing) &body body)
   `(call-with-foo (lambda (,var-x ,var-y) ,@body) ,thing))

(defun call-with-foo (func thing)
  (let ((x (..derive from thing ..)
        (y (..derive from thing ..))
   (funcall func x y)))
因此,它最终会出现在堆栈跟踪中,并且很容易重新定义。 见此:

顺便说一句,回到CL,你应该知道当我写这些 对于xxx宏,我几乎总是给它们打电话 这样我可以打任何一种电话。但我发现我几乎从未使用过 与xxx的通话,即使我是提供该选项的人。 我写它们的主要原因不是为了使用它们,而是为了 重新定义更容易,因为我可以用xxx重新定义调用,而不用 重新定义宏,因此如果 定义改变了


是的,AllegroCl支持宏的跟踪和一般调试。这是一个相当大的努力,不知道有多少好处,但弗兰兹倾向于做好事,使CL更可行。专业提示:有一个选项可以关闭我认为他们所谓的宏源代码级调试,如果您的代码大量使用宏,或者编译时间可能会变得疯狂,您将希望这样做。当您认为需要源代码调试时,只需重新打开它。

注意,SBCL现在也有一个可选的解释器:@RainerJoswig您是否建议您可以使用可选的解释器来实现此目标?您考虑了哪些Allegro功能?我几乎只与Allegro合作,这对我来说是新闻。请注意,这只是一个关于步进的话题。我只是假设它们可以被追踪,等等。我自己从来不使用源代码调试器。我想我在堆栈跟踪中看到过宏。
[1] cl-user(6): :zoom :all t
Evaluation stack:

... 4 more newer frames ...

   ((:runsys "lisp_apply"))
   [... sys::funcall-tramp ]
   (excl::error-from-code 17 nil ...)
   (sys::..runtime-operation "integer_divide" :unknown-args)
   (excl::/_2op 10 0)
 ->(/ 10 0)
   [... excl::eval-as-progn ]
   (block foo (m x))
   (foo 0)
   (sys::..runtime-operation "comp_to_interp" 0)
   [... excl::%eval ]
   (eval (foo 0))
(defmacro with-foo ((var-x var-y thing) &body body)
   `(let ((,var-x (..derive from ,thing ..))
          (,var-y (..derive from ,thing ..)))
       ,@body))
(defmacro with-foo ((var-x var-y thing) &body body)
   `(call-with-foo (lambda (,var-x ,var-y) ,@body) ,thing))

(defun call-with-foo (func thing)
  (let ((x (..derive from thing ..)
        (y (..derive from thing ..))
   (funcall func x y)))