【问题标题】:Forth, interpreted or compiled?第四,解释还是编译?
【发布时间】:2015-11-01 00:56:39
【问题描述】:

假设 Forth 程序可以“编译”,但如果它们的单词仅在运行时进行评估,我不明白这是怎么回事。例如,单词DOES> 存储用于在运行时进行评估的单词。如果这些词包含 EVALUATEINTERPRET 词,那么字典将需要运行时。

为了支持这样的陈述,这意味着整个单词列表(字典)必须嵌入到程序中,本质上是解释程序(不是编译程序)所做的。

这似乎会阻止您使用 Forth 编译小程序,因为整个字典必须嵌入到程序中,即使您只使用了字典中的一小部分单词。

这是正确的,还是有什么方法可以在不嵌入字典的情况下编译 Forth 程序? (也许根本不使用运行时单词??)

【问题讨论】:

    标签: compilation forth


    【解决方案1】:

    Forth 程序可以使用或不使用词头进行编译。标题包括单词名称(称为“名称空间”)。

    在您描述的场景中,程序可能包含运行时评估调用,例如EVALUATE,将需要标头。

    • 字典可以分为三个逻辑上不同的部分:名称空间、代码空间和数据空间。程序执行需要代码和数据,通常不需要名称。

    • 普通的 Forth 程序通常不会进行任何运行时评估。所以在大多数情况下,编译程序中不需要这些名称。

    • DOES> 之后的代码已编译,因此不会在运行时进行评估。它在运行时执行

    • 即使包含名称,它们通常也不会增加程序大小。

    • 许多 Forth 确实有办法从程序中省略名称。有些有一个开关来删除单词标题(名称)。其他有交叉编译器,在编译时将名称保留在主机系统中,但生成没有名称的目标代码。

    【讨论】:

    • 是的,但是 DOES> 子句中可以包含 EVALUATE 或 INTERPRET 词。我已经更新了我的答案以澄清这一点。
    • @TylerDurden,any 单词中可以包含 EVALUATE。单词的 DOES> 部分没有什么特别之处。
    • 由于很长时间没有进一步的答案,我已经接受了这个答案,但它确实完全回答了我的问题,因为它确实解决了程序是否需要将整个字典包含在“编译”程序,以及这是否会取消 Forth 程序被认为被编译的资格。
    • 如果您需要有关这方面的更多信息,请随时发布新问题!
    【解决方案2】:

    不,整个字典不需要嵌入,也不需要编译。剩下的只是使用的单词列表及其父单词(&祖父母,)。并且单词的名称不是必需的,单词位置就足够了。 Forth 用这种方法编译的代码可以尽可能地紧凑,在可执行文件大小上可以媲美甚至超过汇编语言。

    举例证明:Tom Almy 的 ForthCMP,一个 80 年代至 90 年代的 MSDOS 编译器,可将可执行代码大幅缩减。它的自述文件说:

     .    Compiles Forth into machine code -- not interpreted.
    
     .    ForthCMP is written in Forth so that Forth code can be executed
          during compilation, as is customary in Forth applications.
    
     .    Very fast -- ForthCMP compiles Forth code into an executable file
          in a single pass.
    
     .    Generated code is extremely compact. Over 110 Forth "primitives"
          are compiled in-line. ForthCMP performs constant expression
          folding, strength reduction, register optimization, DO...LOOP
          optimization, tail recursion, and various "peephole"
          optimizations.
    
     .    Built-in assembler.
    

    4C.COMdosemudosbox 等模拟器下运行。

    "Hello World" 编译为 117 字节的 .COM 文件,a wc program 编译为 3K .COM 文件(来自 5K 的源代码)。没有字典或外部库,(除了标准的 MSDOS 调用,即它运行的操作系统)。

    【讨论】:

      【解决方案3】:

      Forth 可能会让人难以接受,因为该语言没有标准实现。人们看到的大部分内容来自 Forth 的早期,当时作者(查尔斯·摩尔)还在摸索自己的想法。或者更糟糕的是,人们称之为 Forth 的自制系统,因为它有一个堆栈但实际上不是 Forth。

      那么 Forth 是解释的还是编译的? 简短回答:两者都有

      早年: Forth 有一个面向程序员的文本解释器。所以解释:检查

      但是... ':' 字符启用了编译器,它“编译”了语言中单词的地址,因此它被“编译”但不是作为本机机器代码。它是代码在内存中的地址列表。聪明的部分是这些地址可以用一个列表“解释器”运行,在大多数机器上只有 2 或 3 条指令,而在旧的 8 位 CPU 上还有更多。这意味着它仍然非常快并且非常节省空间。 这些系统更像是一个映像系统,所以是的,系统与您的程序一起运行,但其中一些系统内核在包括编译器和解释器在内的整个运行时为 8K 字节。不是繁重的工作。

      这是大多数人认为的 Forth。请参阅 JonesForth 获取一个有文字的示例。 (这在当时被称为“线程代码”,不要与多线程混淆)

      1990 年代 Forth 大师和 Chuck Moore 开始意识到 Forth 语言原语可能只有现代机器上的一条机器指令,所以为什么不只编译指令而不编译地址。这在 32 位机器上变得非常有用,因为地址有时比指令大。然后,他们可以用处理器的本机 CALL/Return 指令替换小 3 指令解释器。这被称为子例程线程。前端解释器并没有消失。它只是启动了本机代码子例程

      今天 商业 Forth 系统生成本地代码,内联许多/大多数原语并执行您在现代编译器中看到的许多其他优化技巧。 他们仍然有一个面向程序员的解释器。 :-)

      您还可以购买(或构建)Forth 交叉编译器,为不同的 CPU 创建独立的可执行文件,包括多任务、TCP/IP 堆栈,猜猜看,该文本解释器可以作为远程选项编译成可执行文件如果需要,可以进行调试和配置。

      那么 Forth 是解释的还是编译的?还是两者兼而有之。

      【讨论】:

        猜你喜欢
        • 2016-11-19
        • 2011-07-01
        • 2014-04-05
        • 1970-01-01
        • 2011-08-05
        • 2010-12-03
        • 1970-01-01
        • 1970-01-01
        • 2020-10-27
        相关资源
        最近更新 更多