假设Forth程序可以"编译",但如果它们的单词只在运行时求值,我不明白这是怎么回事。例如,有一个单词DOES>
,它存储用于在运行时评估的单词。如果这些单词包括EVALUATE
或INTERPRET
单词,则在运行时需要字典。
为了支持这样的语句,这意味着整个单词列表(字典)必须嵌入程序中,本质上是解释程序(而不是编译程序)所做的
这似乎会阻止你使用Forth编译小程序,因为整个字典都必须嵌入程序中,即使你只使用了字典中单词的一小部分。
这是正确的吗?或者有没有办法在不嵌入字典的情况下编译Forth程序?(也许根本不使用运行时单词??)
Forth程序可以使用或不使用单词头进行编译。标题包括单词名称(称为"名称空间")。
在您描述的场景中,程序可能包括运行时评估调用(如EVALUATE
),将需要标头。
-
字典可以分为三个逻辑上不同的部分:名称空间、代码空间和数据空间。程序执行需要代码和数据,而名称通常不需要。
-
一个正常的Forth程序通常不会进行任何运行时评估。因此,在大多数情况下,编译程序中不需要这些名称。
-
DOES>
之后的代码是编译的,因此在运行时不会对其求值。它在运行时执行。 -
即使包含了名称,它们通常也不会增加程序的大小。
-
许多福斯确实有办法在节目中省略这些名字。有些人有一个开关来删除单词标题(名称)。其他编译器具有交叉编译器,在编译时将名称保留在主机系统中,但生成没有名称的目标代码。
否,整个字典不需要嵌入,也不需要编译。所需要的只是使用的单词列表及其父单词(&祖父母,等)。单词的偶数名称是不必要的,单词的位置就足够了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.COM
在类似dosemu
或dosbox
的仿真器下运行。
A";Hello World"编译成117字节的.COM文件,wc
程序编译成3K的.COM文件(源代码为5K)。没有字典或外部库(除了标准的MSDOS调用,即它运行的操作系统)。
Forth可能很难从外部了解情况,因为该语言没有标准实现。人们看到的很多东西都来自福斯的早期,当时作者(查尔斯·摩尔饰)仍在按摩自己的思想。或者更糟的是,人们称之为Forth的自制系统,因为它有一个堆栈,但实际上不是Forth。
那么Forth是解释的还是编译的?简短回答:两种
早年:Forth有一个面向程序员的文本解释器。如此解释:检查
但是。。。":"字符启用了编译器;编译的";语言中单词的地址,所以它是";编译的";但不是作为本机代码。这是代码在内存中的地址列表。聪明的部分是,这些地址可以用列表"来运行;口译员";在大多数机器上只有2或3条指令,而在旧的8位CPU上则有更多指令。这意味着它仍然很快,而且空间效率很高。这些系统更像是一个映像系统,所以是的,系统会与您的程序一起运行,但其中一些系统内核在整个运行时(包括编译器和解释器)是8K字节。吊装不重。
这就是大多数人认为的福斯。参见JonesForth的识字示例。(这在当时被称为"线程代码",不要与多线程混淆)
1990年福斯大师和查克·摩尔开始意识到,在现代机器上,福斯语言原语可能只有一条机器指令那么小,为什么不编译指令而不是地址呢。这在32位机器中变得非常有用,因为地址有时比指令大。然后,他们可以用处理器的本地CALL/Return指令替换little 3指令解释器。这被称为子程序线程。前端翻译并没有消失。它只是启动了本地代码子程序
今天商业Forth系统生成本地代码,内联许多/大多数基元,并执行您在现代编译器中看到的许多其他优化技巧。他们仍然有一个面向程序员的解释器。:-)
你也可以购买(或构建)Forth交叉编译器,为不同的CPU创建独立的可执行文件,包括多任务、TCP/IP堆栈,你猜怎么着,如果你想要的话,文本解释器可以编译成可执行文件作为远程调试和配置的选项。
那么Forth是解释的还是编译的?还是两者都有。
您说得对,执行解释(EVALUATE、LOAD、INCLUDE等)的程序必须有一个字典。这几乎不是缺点,因为对于Linux或MS Windows来说,即使是64位可执行文件也只是50 K。像MSP430这样的现代单板计算机可以将整个字典存储在闪存中。请分别参见ciforth和noforth然后是脚本。如果您使用Forth作为脚本语言,它类似于perl或python。脚本很小,不包含整个语言。不过,它要求在您的计算机上安装该语言。
如果是非常小的计算机,你可以采用交叉编译或使用伞形Forth,字典位于主机上,通过串行线进行通信和编程。这些是通常不需要的特殊技术。在这种情况下,您不能在sbc上使用解释代码,因为那里显然没有字典。
注意:提及DOS>指示并不能使问题更清楚。我建议你把这个删掉。