I wrote a subroutine threaded Forth targeting 68K when I was in college. I defined the runtime environment and dictionary format, then wrote some C code that boot strapped a Macintosh application that loaded a default dictionary, populated some I/O vectors and got the code running. Then I took the Leo Brodie book Starting Forth and started implementing the basic dictionary in 68K assembly language. I started with arithmetic/logic words, then did control structures then word definition/manipulation words. My understanding is that at a minimum you need @, !, +, -, * and /. The rest can be implemented in terms of those, but that's like trying to write an entire graphics library based on SetPixel and GetPixel: it will work, but yikes, why?
I enjoyed the process as there were some really interesting puzzles, like getting DOES> exactly right (and once I had a solid DOES> implementation, I was creating closures that turned into tiny, tiny amounts of code).
A long time ago, I had a book called "Threaded Interpretive Languages", published I think by Byte, that discussed how to implement a Forth-like language (I don't think they ever called it Forth) in Z80 assembly.
You may not have a Z80 handy, or want one, but the book might be instructive.
Why do I know this? My brother, Mikael, wrote #3 and he also wrote a paper about making a "minimal Forth" (in Swedish, though). If I remember correctly he wanted to get a minimal set of operators that could be built in silicon.
I'm still not convinced the question is well-formed. For example, Plinth's instructions can be reduced; after all, * and / can be implemented in terms of + and -, but then '+' can be implemented in terms of a successor function (see the Peano axioms.) Which puts you into the neighborhood of a Turing machine. How do you know where to stop?
Which Forth implementation are you using that doesn't provide this information in the documentation? Given the nature of Forth, it might be implementation-dependent. There's a standard set of words in the dictionary, but whether they got there by assembly/C/whatever or by Forth shouldn't matter, since Forth is by definition a self-extensible language.
Contrary to what you say, generally DROP SWAP etc are considered basic Forth operations. The reason is that if you implement them using memory operations like you suggest, the overall system becomes more, not less complicated.
Also there is no clear distinction in Forth between what is basic and what not. In the 80's a dictionary search would be basic, and coded in assembler for speed, while a modern linux hosted can afford to code that in so called high level.
Also Forthers tend to routinely recode assembler words in high level, and high level words in assembler. I'm the author of ciforth and yourforth.
It is possible to define <= as "> not" as I did in ciforth . But in yourforth I decided that having all of < <= > >= as similar, uniformly looking, small assembler routines was effectively simpler. That is a judgement call, and a matter of taste, certainly not a matter of principle.
In the context I interpret the question as: "What is a reasonable size for the number of primitive operations to arrive at a reasonable powerful Forth with a reasonable speed?"
Clearly you are not interested in clever tricks to get rid of one assembler word at the expense of tremendous overhead as found in some of the threads discussing this subject.
Now you can look at a number of small Forth's like jonesforth yourforth eforth and conclude that mostly one arrives at around 50 to 100 primitives.
Those Forth's are defined in assembler. If you want to define your primitives in c, python or Java , the situation is again different. Now for e.g. the above dictionary search you have a choice between c and Forth. Considerations that have nothing to do with language design come into play. You may be a prolific c-programmer, or you may insist on coding it in Forth because it is a learning project.
One of my favorites is the three-instruction forth of the MSDOS Pygmy Forth by Frank Sergeant. He uses a tethered Forth, I believe, a more fully functioning forth on a PC, a serial link to the target, and peek, poke, execute (basic language terminology) on the target, i.e., read, write, and run.
If you want the most up-to-date, technologically advanced answer, take a look at the 5-bit (32) instruction set forth (page 5 of the PDF, figure 3) in the 144-core forth cpu developed by Charles Moore the father of Forth. Basically, Mr. Moore gave us Forth, allowed us to make a Fork of what he then had, but he continued optimizing it for the rest of his life until now, eventually crystallizing it down to the cpu level (also making a VLSI chip CAD design tool to design his own chips, also designed bottom-to-top in his own ColorForth. That isn't a low-level language, or a high-level language -- that's an omni-level-language!)
The Factor Programming language I consider to be very similar, and has at its core a virtual machine coded in the C (or c++) language
发布评论
评论(8)
此帖子涵盖了您的具体问题。 这是一个全面的实现< /a> 带有完整的文档。
当我上大学时,我编写了一个针对 68K 的子例程线程 Forth。 我定义了运行时环境和字典格式,然后编写了一些 C 代码来引导 Macintosh 应用程序,该应用程序加载默认字典、填充一些 I/O 向量并使代码运行。 然后我拿起 Leo Brodie 的书 Starting Forth 并开始在68K汇编语言。 我从算术/逻辑字开始,然后是控制结构,然后是字定义/操作字。 我的理解是至少需要@、!、+、-、*和/。 其余的可以根据这些来实现,但这就像尝试基于
SetPixel
和GetPixel
编写整个图形库:它会起作用,但是哎呀,为什么呢?我很享受这个过程,因为有一些非常有趣的谜题,比如让
DOES>
完全正确(一旦我有了一个可靠的DOES>
实现,我就创建了闭包,这些闭包变成了极少量的代码)。This thread covers your exact question. Here is a soup-to-nuts implementation with complete documentation.
I wrote a subroutine threaded Forth targeting 68K when I was in college. I defined the runtime environment and dictionary format, then wrote some C code that boot strapped a Macintosh application that loaded a default dictionary, populated some I/O vectors and got the code running. Then I took the Leo Brodie book Starting Forth and started implementing the basic dictionary in 68K assembly language. I started with arithmetic/logic words, then did control structures then word definition/manipulation words. My understanding is that at a minimum you need @, !, +, -, * and /. The rest can be implemented in terms of those, but that's like trying to write an entire graphics library based on
SetPixel
andGetPixel
: it will work, but yikes, why?I enjoyed the process as there were some really interesting puzzles, like getting
DOES>
exactly right (and once I had a solidDOES>
implementation, I was creating closures that turned into tiny, tiny amounts of code).很久以前,我有一本书叫《Threaded Interpretive Languages》,我认为是 Byte 出版的,其中讨论了如何在 Z80 汇编中实现类似 Forth 的语言(我认为他们从未称其为 Forth)。
您可能手边没有 Z80,或者想要一台,但这本书可能具有启发性。
A long time ago, I had a book called "Threaded Interpretive Languages", published I think by Byte, that discussed how to implement a Forth-like language (I don't think they ever called it Forth) in Z80 assembly.
You may not have a Z80 handy, or want one, but the book might be instructive.
comp.lang.forth 上的这篇文章列出了一些“最小的 Forth”。
http://groups.google.com/group/comp.lang。 forth/msg/10872cb68edcb526
为什么我知道这个? 我的兄弟 Mikael 写了#3,他还写了一篇关于制作“最小 Forth”的论文 “(不过是瑞典语)。 如果我没记错的话,他想要获得一组可以内置在芯片中的最小运算符。
This post at comp.lang.forth lists a few "minimal Forths".
http://groups.google.com/group/comp.lang.forth/msg/10872cb68edcb526
Why do I know this? My brother, Mikael, wrote #3 and he also wrote a paper about making a "minimal Forth" (in Swedish, though). If I remember correctly he wanted to get a minimal set of operators that could be built in silicon.
我仍然不相信这个问题的格式正确。 例如Plinth的指令可以减少; 毕竟,
*
和/
可以用+
和-
来实现,但是'+'可以以后继函数的形式实现(参见皮亚诺公理。)图灵机的邻域。 你怎么知道该停在哪里?I'm still not convinced the question is well-formed. For example, Plinth's instructions can be reduced; after all,
*
and/
can be implemented in terms of+
and-
, but then '+' can be implemented in terms of a successor function (see the Peano axioms.) Which puts you into the neighborhood of a Turing machine. How do you know where to stop?您可能还想看看 Hans Bezemer 的 4tH 编译器。
You might also want to take a look at Hans Bezemer's 4tH compiler.
您使用的哪一个 Forth 实现在文档中没有提供此信息? 鉴于 Forth 的性质,它可能依赖于实现。 字典中有一组标准的单词,但它们是通过汇编/C/其他语言还是通过 Forth 到达那里并不重要,因为根据定义,Forth 是一种可自我扩展的语言。
Which Forth implementation are you using that doesn't provide this information in the documentation? Given the nature of Forth, it might be implementation-dependent. There's a standard set of words in the dictionary, but whether they got there by assembly/C/whatever or by Forth shouldn't matter, since Forth is by definition a self-extensible language.
与你所说的相反,通常 DROP SWAP 等被认为是基本的 Forth 操作。 原因是,如果您像您建议的那样使用内存操作来实现它们,则整个系统会变得更加复杂,而不是变得更加复杂。
此外,在 Forth 中,什么是基本的和什么不是基本的之间没有明显的区别。 在 80 年代,字典搜索是基本的,并且为了速度而用汇编程序编码,而现代 Linux 托管可以负担得起所谓的高级编码。
Forthers 还倾向于定期重新编码高级汇编语言,以及汇编语言中的高级语言。 我是 ciforth 和 yourforth 的作者。
可以将 <= 定义为“> not”,就像我在 ciforth 中所做的那样。 但在第四年,我决定拥有所有的< <=> >= 因为类似、外观统一、小型汇编程序例程实际上更简单。 这是一个判断问题,也是一个品味问题,当然不是一个原则问题。
在上下文中,我将问题解释为:“以合理的速度达到合理强大的 Forth 的原始操作数量的合理大小是多少?”
显然,您对以巨大开销为代价来摆脱一个汇编器字的聪明技巧不感兴趣,正如在讨论该主题的一些线程中发现的那样。
现在,您可以查看一些小型 Forth(例如 jonesforth yourforth eforth),并得出结论,大多数情况下会达到大约 50 到 100 个基元。
这些 Forth 是在汇编程序中定义的。 如果您想在 c、python 或 Java 中定义原语,情况又会有所不同。 现在,对于上面的字典搜索,您可以在 c 和 Forth 之间进行选择。 与语言设计无关的考虑因素开始发挥作用。 您可能是一位多产的 C 程序员,或者您可能坚持使用 Forth 进行编码,因为这是一个学习项目。
Contrary to what you say, generally DROP SWAP etc are considered basic Forth operations. The reason is that if you implement them using memory operations like you suggest, the overall system becomes more, not less complicated.
Also there is no clear distinction in Forth between what is basic and what not. In the 80's a dictionary search would be basic, and coded in assembler for speed, while a modern linux hosted can afford to code that in so called high level.
Also Forthers tend to routinely recode assembler words in high level, and high level words in assembler. I'm the author of ciforth and yourforth.
It is possible to define <= as "> not" as I did in ciforth . But in yourforth I decided that having all of < <= > >= as similar, uniformly looking, small assembler routines was effectively simpler. That is a judgement call, and a matter of taste, certainly not a matter of principle.
In the context I interpret the question as: "What is a reasonable size for the number of primitive operations to arrive at a reasonable powerful Forth with a reasonable speed?"
Clearly you are not interested in clever tricks to get rid of one assembler word at the expense of tremendous overhead as found in some of the threads discussing this subject.
Now you can look at a number of small Forth's like jonesforth yourforth eforth and conclude that mostly one arrives at around 50 to 100 primitives.
Those Forth's are defined in assembler. If you want to define your primitives in c, python or Java , the situation is again different. Now for e.g. the above dictionary search you have a choice between c and Forth. Considerations that have nothing to do with language design come into play. You may be a prolific c-programmer, or you may insist on coding it in Forth because it is a learning project.
我最喜欢的一个是 Frank Sergeant 的 MSDOS Pygmy Forth 的三条指令。 我相信,他使用了一个系留的 Forth,一个在 PC 上功能更齐全的 Forth,一个到目标的串行链接,并在目标上进行窥视、戳戳、执行(基本语言术语),即读、写和运行。 /p>
如果您想要最新、技术先进的答案,请查看144核Forth cpu由Forth之父Charles Moore开发。 基本上,Moore 先生给了我们 Forth,允许我们用他当时拥有的东西制作一个 Fork,但他在余生中继续优化它,直到现在,最终将其结晶到 CPU 级别(还制作了 VLSI 芯片 CAD)设计工具来设计自己的芯片,还用自己的 ColorForth 进行了自下而上的设计,这不是低级语言,也不是高级语言 - 这是一种全级语言!)
我认为因子编程语言非常相似,其核心是一个用 C 语言(或c++) 语言
最后,有一个公共域 Forth,名为 pForth,其内核是用 C 编写的。
One of my favorites is the three-instruction forth of the MSDOS Pygmy Forth by Frank Sergeant. He uses a tethered Forth, I believe, a more fully functioning forth on a PC, a serial link to the target, and peek, poke, execute (basic language terminology) on the target, i.e., read, write, and run.
If you want the most up-to-date, technologically advanced answer, take a look at the 5-bit (32) instruction set forth (page 5 of the PDF, figure 3) in the 144-core forth cpu developed by Charles Moore the father of Forth. Basically, Mr. Moore gave us Forth, allowed us to make a Fork of what he then had, but he continued optimizing it for the rest of his life until now, eventually crystallizing it down to the cpu level (also making a VLSI chip CAD design tool to design his own chips, also designed bottom-to-top in his own ColorForth. That isn't a low-level language, or a high-level language -- that's an omni-level-language!)
The Factor Programming language I consider to be very similar, and has at its core a virtual machine coded in the C (or c++) language
Finally, there is a public domain Forth called pForth, which has its kernel written in C.