40

我对实现一个 Forth 系统很感兴趣,这样我就可以获得一些构建简单 VM 和运行时的经验。

在开始使用 Forth 时,通常首先了解堆栈及其运算符(DROP、DUP、SWAP 等),因此很自然地将这些视为原始运算符。但他们不是。它们中的每一个都可以分解为直接操作内存和堆栈指针的运算符。后来学习了 store (!) 和 fetch (@),它们可用于实现 DUP、SWAP 等(哈哈!)。

那么什么是原始运算符呢?哪些必须直接在运行时环境中实现,所有其他的都可以在其中构建?我对高性能不感兴趣;我想要一些我(和其他人)可以从中学习的东西。运算符优化可以稍后进行。

(是的,我知道我可以从图灵机开始,然后从那里开始。这有点极端。)

编辑:我的目标类似于引导操作系统或新编译器。我至少需要实现什么,以便我可以用这些原始构建块构建系统的其余部分?我不会在裸硬件上实现它;作为一项教育练习,我会编写自己的最小虚拟机。

4

8 回答 8

23

该线程涵盖了您的确切问题。这是一个包含完整文档的简单实现。

我在大学时编写了一个针对68K的 Forth 线程子程序。我定义了运行时环境和字典格式,然后编写了一些引导 Macintosh 应用程序的 C 代码,该应用程序加载了一个默认字典,填充了一些 I/O 向量并让代码运行。然后我拿了 Leo Brodie 的书《开始》 ,开始用 68K 汇编语言实现基本字典。我从算术/逻辑字开始,然后是控制结构,然后是字定义/操作字。我的理解是,您至少需要@、!、+、-、* 和 /。其余的可以根据这些来实现,但这就像尝试基于SetPixeland编写一个完整的图形库GetPixel:它会工作,但是哎呀,为什么呢?

我喜欢这个过程,因为有一些非常有趣的谜题,比如DOES>完全正确(一旦我有一个可靠的DOES>实现,我正在创建变成很小的代码的闭包)。

于 2009-01-02T21:26:10.893 回答
13

很久以前,我有一本名为“Threaded Interpretive Languages”的书,我认为是 Byte 出版的,它讨论了如何在 Z80 汇编中实现类似 Forth 的语言(我认为他们从未将其称为 Forth)。

您可能手边没有 Z80,或者想要一个,但这本书可能很有启发性。

于 2009-01-02T21:13:10.527 回答
8

comp.lang.forth 上的这篇文章列出了一些“最小的 Forths”。

http://groups.google.com/group/comp.lang.forth/msg/10872cb68edcb526

为什么我会知道这个?我的兄弟,Mikael,写了#3,他还写了一篇关于制作“最小的​​ Forth”的论文(虽然是瑞典语)。如果我没记错的话,他想获得一组可以内置在硅片中的最小运算符。

于 2009-01-02T23:55:56.520 回答
4

我仍然不相信这个问题是正确的。例如,可以减少 Plinth 的指令;毕竟,*and/可以用 and 来实现+-但是 '+' 可以用后继函数来实现(参见Peano 公理。)这让你进入了图灵机的附近。你怎么知道在哪里停下来?

于 2009-01-02T23:19:01.850 回答
4

您可能还想看看 Hans Bezemer 的4tH compiler

于 2009-01-03T13:29:31.290 回答
2

您使用的哪个 Forth 实现未在文档中提供此信息?鉴于 Forth 的性质,它可能依赖于实现。字典中有一组标准的单词,但它们是通过汇编/C/其他方式还是通过 Forth 到达那里并不重要,因为根据定义,Forth 是一种可自我扩展的语言。

于 2009-01-02T21:01:00.757 回答
1

与您所说的相反,通常 DROP SWAP 等被认为是基本的 Forth 操作。原因是,如果您按照您的建议使用内存操作来实现它们,整个系统会变得更加复杂,而不是更复杂。在 Forth 中也没有明确区分什么是基本的和什么不是。在 80 年代,字典搜索将是基本的,并以汇编程序编码以提高速度,而托管的现代 linux 可以负担得起所谓的高级编码。此外,Forthers 倾向于例行地用高级语言重新编码汇编器字,并用汇编器重新编码高级字。我是 ciforth 和 yourforth 的作者。可以像在 ciforth 中那样将 <= 定义为 "> not" 。但是在你以后,我决定让所有的 < <= > >= 看起来相似,外观一致,小型汇编程序例程实际上更简单。

在上下文中,我将问题解释为:“以合理的速度达到合理强大的 Forth 的原始操作数量的合理规模是多少?” 显然,您对以巨大开销为代价摆脱一个汇编器字的巧妙技巧不感兴趣,正如在讨论该主题的一些线程中发现的那样。

现在,您可以查看一些小型 Forth,例如 jonesforth yourforth eforth,并得出结论,大多数情况下,其中一个到达大约 50 到 100 个基元。那些 Forth 是在汇编程序中定义的。如果您想在 c、python 或 Java 中定义您的原语,情况又有所不同。现在对于例如上面的字典搜索,您可以在 c 和 Forth 之间进行选择。与语言设计无关的考虑开始发挥作用。你可能是一个多产的 c 程序员,或者你可能坚持用 Forth 编码,因为它是一个学习项目。

于 2018-01-19T15:41:59.623 回答
1
  1. 我最喜欢的一个是Frank Sergeant的 MSDOS Pygmy Forth 中的三条指令。我相信他使用了一个系留的 Forth,我相信,一个在 PC 上功能更完整的 Forth,一个到目标的串行链接,以及在目标上的 peek、poke、execute(基本语言术语),即读、写和运行。

  2. 如果您想要最新、技术最先进的答案,请查看Charles Moore 开发的144 核第四 cpu中列出的 5 位 (32) 指令(PDF 第 5 页,图 3)福斯之父。基本上,Moore 先生给了我们 Forth,让我们可以将他当时拥有的 Fork设计自己的芯片的设计工具,也在他自己的 ColorForth 中从下到上设计。那不是低级语言,也不是高级语言——那是全能级语言!)

  3. 我认为因素编程语言非常相似,其核心是一个用 C(或 C++)语言编码的虚拟机

  4. 最后,还有一个名为 pForth 的公共领域 Forth,它的内核是用 C 语言编写的

于 2019-07-23T04:58:37.807 回答