Ruby块是如何实现的(在编译器中)

Ruby块是如何实现的(在编译器中),ruby,compiler-construction,scopes,Ruby,Compiler Construction,Scopes,我想实现一个类似于Ruby块的语言构造。所以 main() { i = 123 array.function(|x| { puts x + i; }) //the block needs access to the local variable i } 应该可以。我看了一个小时的源代码,但由于我不太擅长C,我仍然不知道他们是如何实现它的。我的第一个想法是它是一个嵌套函数,地址作为参数传递,但我不确定嵌套函数如何访问局部变量,因为在大多数语言中这似乎是不可能的。如果有人能告诉我如

我想实现一个类似于Ruby块的语言构造。所以

main()
{
    i = 123
    array.function(|x| { puts x + i; }) //the block needs access to the local variable i
}

应该可以。我看了一个小时的源代码,但由于我不太擅长C,我仍然不知道他们是如何实现它的。我的第一个想法是它是一个嵌套函数,地址作为参数传递,但我不确定嵌套函数如何访问局部变量,因为在大多数语言中这似乎是不可能的。如果有人能告诉我如何实现这一点,我将非常高兴

这是C语言中代码块和收益的实现,它可能会对您有所帮助。

这里是C语言中代码块和成品的实现,它可能会对您有所帮助。

调用新函数时,您能将相关堆栈推送到新函数上吗?调用函数时,我只需将参数(每个参数有4个字节)推送到堆栈上,并进行调用,从而推送到ras上的返回地址。块可以作为匿名函数实现;但是,如果它们没有在被调用的函数中被提升(没有
&block
),那么它们可以在当前帧上被完全声明/模拟。我不确定“frame”是什么意思,你是指函数prolog/epilog吗?目前,对我来说,stackFrame.push(bp)是这样的;bp=sp;sp-=(int)ip@MoritzSchöfl包含函数的调用堆栈。然而,这需要知道块在被调用方内部没有被提升。当调用新函数时,你能将相关堆栈推到新函数的堆栈上吗?当我调用函数时,我只需将参数(每个参数有4个字节)推到堆栈上,并进行调用,从而推送ras上的返回地址。块可以作为匿名函数实现;但是,如果它们没有在被调用的函数中被提升(没有
&block
),那么它们可以在当前帧上被完全声明/模拟。我不确定“frame”是什么意思,你是指函数prolog/epilog吗?目前,对我来说,stackFrame.push(bp)是这样的;bp=sp;sp-=(int)ip@MoritzSchöfl包含函数的调用堆栈。然而,这需要知道被调用方内部的块不会被解除。有趣而可怕。。遗憾的是,更多的语言没有采用类似LISP(“AST”)的宏:(有趣又可怕。)遗憾的是,更多的语言没有采用类似LISP(“AST”)的宏:(