Clisp“程序堆栈溢出. RESET"在(cadr)上.如何? [英] Clisp "Program stack overflow. RESET" on a (cadr). How?

查看:106
本文介绍了Clisp“程序堆栈溢出. RESET"在(cadr)上.如何?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我(仍然)将代码从Franz Lisp移植到Common LISP.现在,我似乎已经将翻译器推到一个奇怪的角落,炸毁了它.

I'm (still) porting code from Franz Lisp to Common LISP. Now I seem to have pushed the interpreter into a strange corner where it blows up.

[11]> (setq fff (cadr contextstack))    
*** - Program stack overflow. RESET

现在怎么会导致堆栈溢出?递归在哪里?

Now how can that cause a stack overflow? Where's the recursion?

我可以确定长度:

[12]> (length contextstack)
79

describe有效.这仅仅是长描述"输出的开始.

describe works. This is just the beginning of long "describe" output.

[13]> (describe (cadr contextstack))

(# . #1=#) is a cons.

 #<FUNCTION POPPATTERN (NODE) (DECLARE (SYSTEM::IN-DEFUN POPPATTERN)) (BLOCK POPPATTERN (MAPONE # #) (XEPATTERN NODE #))> is an interpreted
 function.
 Argument list: (NODE)

 #1=# is a structure of type ENODE.
 Slots:
   EROOT           =
  #1=#S(ENODE :EROOT #1# :EQCLASS #1# :ESUCCESSORS ALLTRUE! :ESLENGTH NIL :EPREDECESSORS NIL :ECONGRUENT NIL :EDEMON NIL :EMERGEDEMON NIL
        :EPATTERN

;;; much more

但是几乎所有适用于contextstack的内容都会随着堆栈溢出消息而崩溃.

But almost anything else applied to contextstack blows up with the stack overflow message.

结构ENODE包含到其他ENODE项的链接,并且存在循环性,这可能会导致一些代码循环.但是cadr吗?那个怎么样 甚至有可能吗?

The structure ENODE contains links to other ENODE items, and there is circularity which could make some code loop. But cadr? How is that even possible?

原始代码使用了"hunks",这是1970年代的MacLISP功能.我将其转换为使用Common LISP结构,并且可能损坏了某些内容.

The original code used "hunks", a MacLISP feature from the 1970s. I converted it to use Common LISP structs, and may have broken something.

这一切都是解释性的;我什么都没编译.安全级别是默认设置.我尝试添加(proclaim '(optimize (safety 3)))来强制执行更多检查,但是并没有改变任何内容.

This is all running interpretive; I haven't compiled anything. Safety level is the default. I tried adding (proclaim '(optimize (safety 3))) to force more checking, but it didn't change anything.

如果要重现此代码,请下载

If you want to reproduce this, download the code in

https://github.com/John-Nagle/pasv /tree/master/src/CPC4

开始剪辑",执行(load 'setup),然后开始查看contextstack.在程序初始化时,任何中断都将在早期发生.

start "clisp", do (load 'setup), and then start looking at contextstack. Whatever is breaking is happening early, as the program is initializing.

推荐答案

如何获取错误

可能是错误在打印中,而不是cadr.您可以通过进行验证

How you got the error

Chances are, the error is in printing, not cadr. You can verify it by doing

(progn (cadr contextstack) nil)

应该可以正常工作.

如果它仍然爆炸,则应检查cadr是否引发异常(然后错误消息将包含圆形对象并爆炸):

If it still blows up, you should check if cadr raises an exception (and then the error message would contain a circular object and blow up):

(and (consp contextstack)
     (consp (cdr contextstack)))

如何避免错误

CLISP常见问题解答说:

当您尝试打印圆形对象(LISTSTRUCTURE-OBJECTVECTOR等)和

You will always get a stack overflow when you try to print a circular object (LIST, STRUCTURE-OBJECT, VECTOR etc) and *PRINT-CIRCLE* is NIL. Just set *PRINT-CIRCLE* to T.

请注意,这不是 CLISP特有的,当*print-circle*nil时,任何ANSI Common Lisp都应该出现相同的错误.

Note that this is not CLISP-specific, you should get the same error with any ANSI Common Lisp when *print-circle* is nil.

在您的特定情况下,请仔细查看(describe (cadr contextstack))的输出:

In your specific case, look closely at the output of (describe (cadr contextstack)):

(#.#1 =#)是一个缺点.

(# . #1=#) is a cons.

#=标记由 打印机,以避免在打印圆形对象时出现堆栈溢出.

This #= notation is used by the printer to avoid stack overflows when printing circular objects.

PS. 您现在欠我10个zo虫:-)

这篇关于Clisp“程序堆栈溢出. RESET"在(cadr)上.如何?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆