Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/5.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
Assembly 在编译器中,在goto目标/标签上实现闭包的最佳方法是什么?_Assembly_Compiler Construction_Closures - Fatal编程技术网

Assembly 在编译器中,在goto目标/标签上实现闭包的最佳方法是什么?

Assembly 在编译器中,在goto目标/标签上实现闭包的最佳方法是什么?,assembly,compiler-construction,closures,Assembly,Compiler Construction,Closures,考虑以下常见的Lisp代码: (let((闭包)) (defun) (标记体) (开始:开始) :这里 (写一行“Got:here”) (怪异归来) :开始 (setf闭合(λ() (走:这里) (激活) (取消激活() (全部关闭) 调用weird会导致打印get:here。因此,存储在closure中的函数在go标记:here上关闭。公共Lisp和具有以下限制,即转移的目标必须是词汇可见的tagbody形式;例如,以下内容无效: (定义错误() (围棋:内线) (标记体:内部 (写一行“不

考虑以下常见的Lisp代码:

(let((闭包))
(defun)
(标记体)
(开始:开始)
:这里
(写一行“Got:here”)
(怪异归来)
:开始
(setf闭合(λ()
(走:这里)
(激活)
(取消激活()
(全部关闭)
调用
weird
会导致打印
get:here
。因此,存储在
closure
中的函数在
go
标记
:here
上关闭。公共Lisp和具有以下限制,即转移的目标必须是词汇可见的
tagbody
形式;例如,以下内容无效:

(定义错误()
(围棋:内线)
(标记体:内部
(写一行“不可能”))
当然,对于Lisp的语法,这很有意义;我们无法转到
:内部
,因为
转到
不在其范围内。但是,Algol和C等语言没有此限制:

void权限(void)
{
后藤内;
{
内部:printf(“可能发生”);
}
}
假设我想为一种类似Algol的语言实现一个带有闭包的编译器,并为一个基于堆栈的虚拟机生成字节码。(关键是我不受某些真实计算机的体系结构甚至现有虚拟机的体系结构的限制。) 这种语言要求像在Pascal中一样声明标签,尽管声明可以在任何地方,而不仅仅是在函数/过程的开头,而且标签是符号的,而不是数字的

将标签/标记“绑定”到代码中的某个位置在公共Lisp中有相同之处,在这种语言中也应如此;一旦包含标签声明的块退出,传输点将变为无效。例如,在
weird
中的
tagbody
之后调用
activate
,将导致违反此约束。然而,否则,标签可以放在其声明的词法范围内的任何地方,包括内部块中

有关此工具的实际使用,请参见语言标准中给出的Common Lisp的示例扩展(在注释部分中),或者(如果您还不熟悉Common Lisp的条件系统,那么这将不是很有意义。)我不确定是否有合理的方法将关闭的goto应用到内部块中……然而,忽略该功能将是一个随机限制

将控制权转移到闭包中是没有意义的,转移到任何过程的主体中也是没有意义的

在这种情况下,支持关闭goto标签的最佳方式是什么?关闭变量绑定足够简单,但允许关闭传输点还需要什么

我认为会有一个标签环境和词汇环境。这种环境会是什么样子(如果这是一种方式)?当goto将目标锁定在比闭合点定义更深的层面时,并发症似乎会出现。在标签无法到达后,如何使传输点无效?也许(见)可以作为一个榜样;它实现了所需的语义,只是能够转到内部标签

Common Lisp还有一个操作符,它建立了一个也可以关闭的命名出口点。然而,我相信,这可以使用与闭式goto相同的机制来实现

(顺便说一句,我很确定在Algol 68中可以定义一个相当于
的古怪的
,只有语法上的差异。事实上,我很确定Algol 68实现需要部分解决这个问题中描述的问题,尽管Algol 68通常没有闭包。)


缔约国声明如下:

在Scheme中,如果需要,continuations甚至可以将控件从外部上下文移动到内部上下文。这种对下一步执行什么代码的几乎无限的控制使得复杂的控制结构(如协同路由和协作多任务)相对容易编写

这对我来说意味着延续绝对是一个可行的策略。我以前犹豫不决,主要是出于无知,但现在我做了一些进一步的研究,这个想法更具吸引力,特别是因为“免费”的合作项目听起来不错

我的第一个想法是拥有一个由连续体组成的标签环境;通过执行(激活?)相应的延续来执行到标签的传输。这些延续必须在运行时动态设置。关闭一组标签的闭包将获得标签环境的副本

然而,这个想法似乎有一些问题。目前,这些延续的范围是无限的——我认为这可以通过在环境中保留对延续的引用来解决,当声明超出范围后标签环境被拆除时,这些引用可能会失效。一个更紧迫的问题是,要使这项工作成为一项对执行模式的实质性反思,似乎是必要的,以适应包括延续在内的情况。我应该提到,我不想要一流的延续;他们比后藤可怕得多

如果没有封闭标签,这种语言可以用一个类似于经典Algol机器的虚拟机来实现:有一个“显示”来跟踪词汇环境,一个封闭在创建时存储显示的副本。在我看来,有了封闭的标签,一切都变得复杂得多。我觉得我好像缺少了一个合理的方法来处理这些问题,一个不会带来像连续剧那样沉重的东西的方法。我还想把它改成b