forth系统入门指导手册0-11(告一段落)_第1页
forth系统入门指导手册0-11(告一段落)_第2页
forth系统入门指导手册0-11(告一段落)_第3页
forth系统入门指导手册0-11(告一段落)_第4页
forth系统入门指导手册0-11(告一段落)_第5页
已阅读5页,还剩10页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、forth系统入门指导手册0-11(告一段落).txt24生活如海,宽容作舟,泛舟于海,方知海之宽阔;生活如山,宽容为径,循径登山,方知山之高大;生活如歌,宽容是曲,和曲而歌,方知歌之动听。第0章 前言 这是一本游戏手册,是的,你没听错,因为forth不能给你带来显而易见的实际利益,几乎没什么公司会招聘一个forth程序员,因为forth太冷门了,所以你只能把它当成一个游戏来玩。 在推销一件东西的时候,吹嘘它的优点是必须的,虽然对forth吹得天花乱坠的溢美词很多,但是冷门还是冷门,所以我也懒得吹了。简单说说它的优缺点吧 优点:可以迅速适应不同的CPU(可移植性好),结构小巧紧凑,模块化优秀,

2、可以自制语法,足够自由。 缺点:与主流语言差异很大,太过自由,过于个性化,只有一个基本的统一标准,对程序员自身思维水平的要求比较高,没有足够的函数库,需要重新发明轮子,使用者稀少,趋近消亡。 本文的目标是让那些有一定编程经验、对forth感兴趣、但是对forth和汇编毫无概念的业余爱好者也能看得懂。这里是forth所有版本的编译器/compilers.html,本文主要是以eforth为例,理由是够简陋。我会把我反复咀嚼过的东西再吐出来喂给你们吃的,哇哈哈哈哈哈!第1章 简单的语法 还记得以前我们是怎样学英文的吗?现在来回顾一下吧 he is a bold

3、 man he :他 is :是 a :一个 bold : man :人 我不认得bold这个单词,怎么办?聪明好学的同学提供了一个方法,查字典。OK,那就查吧。 bold:大胆的 好了,现在我知道怎么翻译了,他就是一个胆儿肥的人。以后再遇到不懂的单词,我就知道该去查字典了。 英文是这样,中文也是这样,碰到不懂的字,我们就会去查字典,弄清这个句子里所有的字是什么意思的时候,我们也就完全明白这个句子是什么意思了。 让我们继续翻译 he is a sdf man sdf:胆大的;是bold的同义词 “sdf?你瞎编的吧?”没错,就是瞎编的,而且我还成功忽悠了刚刚学英语的小朋友,这让我很有成就感!但

4、是大朋友们就不那么好忽悠了,他们会用怀疑的目光看着我,然后转过头去翻字典,这让我很没成就感! 为了将忽悠进行到底,我决定贿赂该字典的出版社,让他们把我瞎编的词收录到他们的字典里,然后自掏腰包出版新字典。这样一来,当大朋友们在字典上查不到sdf时,我会告诉他们说,他们用的是过了期的字典,然后递给他们一本我自费出版的新字典,再然后。他们全信了!这让我的虚荣心得到了极大的满足,哈哈哈哈哈!现在,我可以在跟别人沟通交流时毫无障碍的使用sdf这个流行词了。 以上所说的就是forth里最基本的内容:字,字典,造字。forth里有几十个最基本的字,它们被人称作code字、核心字、原语、一级字等等等等。下一个

5、阶层的字则是由这些最基本的字或本阶层的字组合而成,被称作colon字、扩展字、冒号字、二级字等等等等。拿上面的英文句子举个例子:输入: : he. 他 ; : is. 是 ; : a. 一个 ; : bold. 胆大的 ; : sdfbold ; : man. 人 ; he is a sdf man 屏幕显示:他是一个胆大的人 需要说明的一点就是: bold必须在: sdf之前,否则forth会告诉你没有sdf这个字。 forth的语法就是按顺序执行每一个字,碰到字典里没有的字的时候,就给出提示,并终止运行,这语法够简单吧? :(冒号)是一个用来定义一个新字的字,;(分号)是一个表示语句结束的

6、字,.是一个用于输出字符串的字,与输出内容用空格隔开。在forth里面,“有且只有”字,这保证了forth整体上的统一性。如果还要再算上一个,那就是空格,它是使用频率最高的符号,用于区分字与字。 有人要问了,为什么要把冒号放在顶头,这不是完全违反了人类的语法习惯?我的回答是,forth这种反人类反社会的语法不是专门给人看的,是给机器看的,但是人也能看懂。就像听老外说中国话,虽然他时不时的反一下人类,但你也能听懂他说的是什么意思。 另一个反人类的语法 1+2=? 如果你这样询问forth,它会告诉你没有“1+2=?”这个字。那么应该怎么问呢?是这样的,问它“1 2 + .”(“.”是输出十进制数

7、值),然后它会告诉你“3”,再然后你又该骂它反人类反社会了,(_)我想我不需要再重复的解释理由了吧? 第2章 forth机的基本结构 大家都知道堆栈吧?先进先出的堆和先进后出的栈。什么?你不知道?嗯,内事问百度。什么,你连百度都不想问?你太懒了,我很不喜欢除了自己以外的懒人。 主流编程语言习惯 由编译器自动分配释放栈区(stack) ,存放函数的参数值,局部变量的值等。而堆区(heap) 一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收 。 而forth机的本质就是先进后出的堆栈机(stack computer),很少用到堆,它有两个栈,一个是嵌套调用函数(也就是字)的返回栈(

8、return stack),另一个是存放局部变量的数据栈(data stack) 区别是什么?主流语言需要定义变量,给变量起名,还要考虑这名字好不好懂,会不会跟其他变量名重复。forth不是这样,它需要起名的只有函数(字),而局部变量都是只标明是什么类型的无名变量。某人要问了,没名字的变量怎么调用?嗯,这就是堆栈所要发挥的作用了,我只需要把这些参数按调用的先后顺序扔到堆栈上,然后逐一调用即可。某人继续问,万一函数里的无名参数太多呢,怎么记得住?嗯,多了是记不住,但是为什么要把那么多参数放在一个函数里,你就不会拆分成几个函数,让每个函数只处理1到3个参数吗?让每个函数做好自己的事,各行其职,整个

9、程序不就跟着美好了吗? 话题扯远了,继续说stack,上一章的1+2=3在堆栈上的表现是这样的: 1 2 + . 1(放入1) 2(放入2) +(先取出2,再取出1,计算得3,存入3) .(取出并显示3) stack的先入后出就是这样第3章 算术练习题1 为了加深你对stack的理解,来几道小学生程度的算术题,以forth的方式,答案在下章结尾。第1题 1+2+3+4第2题 1+2-3+4第3题 1+2*3+4第4题 (1+2)*(3+4)第4章 算术练习题2-我是骗字数的分割线- 不知道你有没有发觉,上一章你输入数据的顺序和你用笔在纸上计算的顺序是一样,这不是巧合,这只是你思路的顺序,而fo

10、rth只是遵照你的思路在执行。这是forth一个很重要的思想人机一体,你本人能解决的问题,forth就一定能解决,只要你能清晰的剖析自己的思路;但如果连你自己都解决不了,也就别指望forth能帮你解决了。 上一章的答案 第1题 1 2 + 3 + 4 + . 第2题 1 2 + 3 - 4 + . 第3题 2 3 * 1 + 4 + . 第4题 1 2 + 3 4 + * . 接下来就是中学水平的计算题了 示例1: Y=X+5 输入某个数X,求Y 解:X 5 + 示例2: Y=a+b*(c+5) 输入某个数X,求Y 解:c 5 + b * a +练习题Y = 12 + (93 * a / 2

11、+ 432*b)/129+c)*2答案在下章第5章 算术练习题3-我是骗字数的分割线-第1种答案:93 a * 2 /432 b * + 129 / c + 2 * 12 + 第2种答案:还记得之前瞎编的那个同义词吗? : func_a93 * 2 / ; : func_b432 * ; : func_ab+ 129 / ; : func_c+ 2 * 12 + ; a func_a b func_b func_ab c func_c 你是不是觉得第二种方法比第一种更麻烦?既然这样,我这里有3组数据 a=2, b=4, c=6 a=3, b=4, c=5 a=1, b=3, c=6 我用第二种

12、方法算,你用第一种方法算,咱们看看谁算得快。 我只需要输入一遍 : func_a93 * 2 / ; : func_b432 * ; : func_ab+ 129 / ; : func_c+ 2 * 12 + ; a func_a b func_b func_ab c func_c 再输入三遍 a func_a b func_b c func_c 就可以了。 你就老老实实的把那一连串的字符输入三遍吧!思考题 虽然我输入的字符比较少,但是如果数据成百上千,那工作量也够大的,能不能让输入的工作量再少点?第6章 先入后出的stack-茁壮成长的分割线- 继续上一章的思考题 第二种解法重复输入的时候需

13、要输入3个参数和3个自定义的字,3个参数是必不可少的,3个定义字却还能再简化成1个定义字,所以我打算做成a b c func_y,那么输入a b c之后 a b c 按照算式的逻辑,我们应该先从a开始算起,但是,c却把出口堵住了,再瞄了一下c的后面,b也不是什么好鸟。没办法,我只好亲自协管一下,我就不信我不能把这事给管斜了。让a享受最高待遇,让c去垫底,让b夹当中。嗯,现在看起来和谐多了 c b a 首先是a : func_a93 * 2 / ; 假设a func_a计算得出A c b A 然后轮到b了,但是这时候A又开始堵门了。还要协管吗?可A是算出来的,不能像刚开始那样直接协管了。 还记得

14、forth一共有两个stack吗?我们之前一直在用的是数据栈(data stack),而现在我们就要用到返回栈(return stack)了。操作字是r和r(注:eforth的系统命令都是大写字母),这字义很形象吧,不用我解释了吧? 先把大A从DS扔到RS上,然后我们再来收拾小b r DS c b RS A : func_b432 * ; b func_b DS c B 接下来把A拉回来 r DS c B A RS 再让A、B合体 : func_ab+ 129 / ; B A func_ab DS c AB 最后就轮到我们仅存的未经处理的小c了 : func_c+ 2 * 12 + ; C 完

15、整的程序 : func_a93 * 2 / ; : func_b432 * ; : func_ab+ 129 / ; : func_c+ 2 * 12 + ; : func_yfunc_a r func_b r func_ab func_c ; c b a func_y 如果我想用 a b c func_y的这种写法呢?这个问题给你去想第7章 栈顶元素的使用规则和注释 forth在使用栈顶元素的时候有个规则,就是每个元素只能使用一次,使用过后就会被抹去,例如 1 1 .(显示1) 所以在定义一个新字的时候,通常会给这个字加以注释 ( n - ) : . ; ( n1 n2 - n3 ) : +

16、 ; 括号是forth的注释字,就像C语言里的/,强调一下,括号也是“字”,所以必须用空格隔开 -左边代表你要使用的栈元素,-右边代表使用之后去掉刚刚使用过的栈元素之后的变化。 为什么有这种用过就丢的设定?其实forth不是不能保留,但是从大多数时候来看,只需要用一次的情况居多,所以就选择了这种用过就丢的设定。 那么如果想重复使用同一个元素呢?forth提供了dup(n - n n )、over(n1次栈顶 n2栈顶 - n1 n2次栈顶 n1栈顶)和2dup( n1 n2 - n1 n2 n1 n2 ) 例如,显示两次 3 dup . . 其余两个字自己去试第8章 条件判断 forth的if

17、( n - )依然是反人类的,具体情况如下 条件 if 真情况 else 假情况 then 例子 ( n - ) : test if . true else . false then ; 1 test 2 test 0 test 测试结果是0为假情况,非0为真情况 一直忘了说,冒号是把 test 这个字加入字典,但并不执行。另外,需要执行的语句不需要加上分号。 在字写入字典之后即可输入参数进行测试,这也是forth的优点之一容易测试。 (n1 n2 - T|F ) : ; forth提供了小于号,比较栈顶两个元素大小 如果n1n2 ,则换上一个-1(非0,TRUE,真) 如果n1不n2, 则换

18、上一个0(0,FALSE,假) 再试试上面的那个test 3 5 test forth还提供了一个swap( n1 n2 - n2 n1 ),用于交换栈顶和次栈顶 3 5 swap test 现在我想从两个数里挑出比较小的那个 ( n1 n2 - n ) : min2dup r ( x n - x n) for dup next ( x n - x x x x x x x x x x x .) r for * next ; ( x x x x x x x x x x x . - x ) 100 Ncifang (你见过摩天大楼吗?我不但见过,还亲手盖了一座,用栈元素) 写法2:(这个就很省st

19、ack了,给个提示,用over) 记住,写forth程序的时候,心里一定要有两个堆栈。第11章 核心字 核心字是forth中用其他语言(例如汇编、c等等,如果你不用考虑速度问题,还可以用其他高级语言)编写的字,构成形式与forth的语法完全不同,而扩展字则是用核心字组合而来。所以,扩展字只跟核心字的名字和与名字相应的功能有关,与编写核心字的语言无关,这也是forth容易移植的原因,你只需要重新编写几十个核心字,就可以快速的移植。核心字分类计算: um+ um* um/mod ur r drop dup swap 内存读写:! c! c系统相关:push execute exit sp sp!输入:key?输出:emit 退出:bye以上是一些常见的核心字,各个版本的forth选定的核心字数量不一,各自有各自的考虑,这也是forth自由与混乱的源头。核心字相对较多,运行速度也就相对较快,核心字越少,运行速度越慢,传说曾经有人做了一个只有13个核心字的forth,速度就不用提了。有时候为了提高速度,也

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论