Joe*_*nck 13
如果你是从头开始,你真的应该考虑继续传递风格(CPS)转换.
好消息来源包括"LISP in small pieces"和Marc Feeley's Scheme在90分钟的演示中.
到目前为止,似乎没有提到Dybvig的论文.阅读是一种乐趣.基于堆的模型是最容易实现的,但基于堆栈的效率更高.忽略基于字符串的模型.
R. Kent Dybvig."计划的三种实施模式". http://www.cs.indiana.edu/~dyb/papers/3imp.pdf
另请参阅ReadScheme.org上的实施文件. http://library.readscheme.org/page8.html
摘要如下:
本文介绍了方案编程语言的三种实现模型.第一个是基于堆的模型,在大多数Scheme实现中以某种形式使用到目前为止; 第二个是基于堆栈的新模型,在执行大多数程序时比基于堆的模型更有效; 第三个是一个新的基于字符串的模型,旨在用于Scheme的多处理器实现.
基于堆的模型在堆中分配几个重要的数据结构,包括实际参数列表,绑定环境和调用帧.
基于堆栈的模型尽可能在堆栈上分配这些相同的结构.这导致更少的堆分配,更少的内存引用,更短的指令序列,更少的垃圾收集以及更有效的内存使用.
基于字符串的模型在程序文本中分配这些结构的版本,该文本表示为符号串.在基于字符串的模型中,Scheme程序被翻译成FFP语言,专门用于支持Scheme.这种语言的程序由FFP机器直接执行,这是一台多处理器的字符串缩减计算机.
基于堆栈的模型具有直接的实用性; 它是作者Chez Scheme系统使用的模型,是Scheme的高性能实现.一旦机器实现,基于字符串的模型将有助于将Scheme作为FFP机器上FFP的高级替代品.
除了你到目前为止的好答案,我推荐Andrew Appel的 Compiling with Continuations.它编写得很好,虽然没有直接处理C,但它是编译器编写者非常好的想法的来源.
鸡肉维基也有你会发现非常有趣的页面,例如 内部结构和编译过程(其中CPS用编译的实际例子来解释).
延续不是问题:您可以使用CPS实现具有常规高阶函数的那些.天真堆栈分配的问题是尾部调用永远不会被优化,这意味着你不能成为方案.
将方案的意大利面条堆栈映射到堆栈上的最佳方法是使用trampolines:基本上是额外的基础设施来处理非C类调用和退出程序.参见Trampolined Style(ps).
有一些代码说明了这两种想法.
连续性基本上由堆栈的保存状态和上下文切换点处的CPU寄存器组成.至少,您不必在切换时将整个堆栈复制到堆中,您只能重定向堆栈指针.
使用光纤可以简单地实现连续性.http://en.wikipedia.org/wiki/Fiber_%28computer_science%29 .唯一需要仔细封装的事情是参数传递和返回值.
在Windows中,光纤使用CreateFiber/SwitchToFiber系列调用完成.在符合Posix的系统中,可以使用makecontext/swapcontext完成.
boost :: coroutine有一个C++协程的工作实现,可以作为实现的参考点.