我可能对探索像 Forth(或 Factor)这样的基于堆栈的语言感兴趣。我想看到的是如何从头开始逐步构建应用程序。我发现的教程是基本的,并没有帮助我理解更大的图景。在处理大量部件时,考虑如何管理堆栈是令人困惑的。
我一直认为(也许是错误的)学习语言的一个好方法是用它来编写Roguelike游戏。我很难弄清楚一个人如何在一堆东西上杂耍:迷宫、数十种生物、宝藏、角色统计数据等。
默认情况下,Forth 只有少量的工作库,所以一切都必须从头开始编程。原因是,基于堆栈的 Forth 虚拟机将自己标识为一个超薄系统。
根据 Gforth 手册,可以使用现有的 C 库并访问用 C 编写的预编译图形库和游戏引擎。 C项目。
我从头开始用 C 创建了一个库。它提供了一个 add 函数,可以从主程序中调用。这些文件被编译和链接,它工作正常。
### add.c ###
int add(int a, int b) {
return a + b;
}
### add.h ###
int add(int, int);
### main.c ###
#include <stdio.h>
#include "add.h"
void main() {
printf("5 + 7 = %d\n", add(5,7));
}
### compile ###
gcc -c -fPIC add.c
gcc -c main.c
gcc main.o add.o
./a.out
5 + 7 = 12
Run Code Online (Sandbox Code Playgroud)
计划是使用这个来自 Forth 的预编译 c 库。Gforth 编译器为此提供了一个特殊的关键字,它将 Forth …
我使用 TI UniFlash 云工具成功上传了 MSP430G2553 的 Mecrisp Forth 十六进制文件。
(我也使用相同的工具来刷新 MSP430F5529 和 TI Tiva LaunchPad 的其他 Mecrisp Forth 十六进制文件。)
不幸的是,以 9600 波特率运行的 Tera Term 没有响应。
(我已使用相同的Tera Term成功与在 MSP430F5529 和 Tiva 上运行的 Mecrisp Forth 进行对话。)
我关注了早期G2 LaunchPad的硬件RX/TX业务。事实上,最新的EXP430G2ET已经在板上清楚地标明了,并且它带有晶体焊接。
那么我错过了什么?
当我在脚本顶部有一个shebang时,我无法让Gforth运行,例如:
#!/usr/bin/gforth
: pinoke ." I'm a real boy!!! "
pinoke
Run Code Online (Sandbox Code Playgroud)
Unix似乎正在推出gForth,但gForth本身在shebang线上窒息.我不确定如何定义一个单词以使Forth以不同的方式解释shebang线(不是说它不能完成,但我只是不确定它是怎么回事).
我已经考虑过使用脚本将代码文件提供给gForth,但是反复做这件事可能相当尴尬.有没有办法让gForth像其他语言一样接受shebang?
我试图(一步一步)构建我自己的Forth副本以在Mac OS X上运行.
我目前有一个在Apache上运行的Forth版本,在PHP,Ruby和Python上运行localhost.
我想在C中创建一个Forth版本,它将创建一个Forth的本机可执行版本,可以创建任何已编译的Forth代码的本机可执行文件.抱歉半递归的句子.我的目标是从C开始,最后得到我自己的Forth编译器(不再在任何C代码中运行).
我的出发点是尝试将最小的测试程序作为Terminal的二进制可执行文件运行.一旦我能够理解现有的C编译器正在做什么,我就可以为自己的目的修改它的方法.
我在C中创建了一个小的"hello world"程序,最终得到了一个8,497字节的可执行文件,其主要由0x00数组(可能是缓冲区)组成.我的猜测是包含了整个stdio库.
接下来,我创建了我能想到的最小的可能的C程序(除了一个完全无效的程序 - 我希望能够在生成的十六进制中找到我的代码):
int main(void)
{
char testitem;
testitem = 'A';
return -1;
}
Run Code Online (Sandbox Code Playgroud)
这应该给我带来了存储ASCII A的最大可能开销,并且很容易找到所有的返回值.
相反,我最终得到了一个4,313字节的文件.0x41(ASCII"A")有四个位置,但没有一个是MOV立即字节指令的一部分.据推测,0x41存储为常量数据并加载了不同的MOV指令.
同样有很多0x00数组(3,731字节,或者除了402字节之外).据推测,目标文件中有某种标题数据(在终端中可以正确运行并且信号为-1),谁知道还有什么.
目前我并不关心拥有应用程序包 - 在终端中运行是我的短期目标.一旦我完成了第一步,我就可以继续完整的应用程序了.
有关如何确定我需要在目标文件中具有哪些内容以使其正确用作终端工具的任何建议?
据说Forth程序可以"编译"但我不知道如果它们只有在运行时评估的单词,那是怎么回事.例如,存在DOES>用于在运行时存储用于评估的单词的单词.如果这些单词包含一个EVALUATE或一个INTERPRET单词,那么字典就会有运行时需求.
为了支持这样的陈述,这意味着整个单词列表(字典)必须嵌入到程序中,基本上是解释程序(不是编译程序)所做的.
这似乎会阻止您使用Forth编译小程序,因为整个字典必须嵌入到程序中,即使您只使用字典中的一小部分单词.
这是正确的,还是有一些方法来编译Forth程序而不嵌入字典?(也许根本不使用运行时单词?)
正如我记得FIG-Forth的'tick',当一个单词不在单词表中时,它可以在没有堕胎的情况下使用:
' the_word
Run Code Online (Sandbox Code Playgroud)
如果它出现在单词列表中,则引用该单词,否则给出"假".
是否有可能在ANS Forth中构建类似于与[if],[then]和[else]一起使用的东西?
在Forth中,在重新定义单词的情况下,使用重新定义的单词的另一个单词的预期行为是什么?例如,如果x来电y:
: Y ." Old Y " CR ;
: X 10 0 DO Y LOOP ;
\ ...
: Y ." New Y " ;
Run Code Online (Sandbox Code Playgroud)
那么在重新定义之后Y,应该输出什么X,Old Y或者New Y?
我开始阅读Thinking Forth.在书中,作者提到了一个三线模块系统,其中提到了Forth会议的记录.这是一个PDF,其中包含从第14页开始的模块系统的描述(打印时为132).
这是关于如何使用三个定义的单词的说明INTERNAL,EXTERNAL以及MODULE.
模块是INTERNAL和MODULE之间的程序的一部分.在INTERNAL和EXTERNAL之间写入模块本地的常量,变量和例程的定义.在模块外部使用的定义写在EXTERNAL和MODULE之间.[例程的局部变量]在INTERNAL和EXTERNAL之间定义.引用它们的例程在EXTERNAL和MODULE之间定义.
这是代码本身:
: INTERNAL ( --> ADDR) CURRENT @ @ ;
: EXTERNAL ( --> ADDR) HERE ;
: MODULE( ADDRl ADDR2 --> )PFA LFA ! ;
Run Code Online (Sandbox Code Playgroud)
我正在阅读这本关于如何编写软件的想法,而不是如何在Forth的任何特定实现中编程,所以我不熟悉代码中使用的内置字,但我是对这个模块系统很好奇.有人能解释它是如何工作的吗?
我正在写我的第一个Forth(在ARM上)。我想在裸机上使用它,因为我认为这就是Forth的重点。但是,在没有Linux系统调用的情况下,我无法找到有关如何编写KEY,EMIT和朋友(基本上是处理键盘)的信息和示例。我也尝试读取引导加载程序源代码(U-Boot),但是显然这超出了我的理解范围。
您能帮我在裸机ARM组件中编写键盘处理程序循环和REPL吗?一些类似的,但对于ARM。我正在使用Cortex-A8 CPU(ARMv7)。