上周在朋友中问了一圈,发现没有几个人知道Logo语言的,或许,这门古老的语言现在用的人已经非常少了,除了国外有少量的用户将Logo语言用于教育外,估计国内不会有人使用这门语言。其实,Logo语言本来也就是以编程教育为目的的一门寓教于乐的编程语言,因此,对于小朋友学计算机编程还是有些帮助的,使用Logo控制小海龟在屏幕上画出各种美妙的图案,可以让小朋友对编程产生浓厚的兴趣。
在90年代我刚刚接触电脑的时候,当时国内比较流行的就是各种品牌的学习机,比较有名的有中华学习机、小霸王学习机、裕兴电脑等。其中有些学习卡中就自带LOGO绘图语言,比如,裕兴电脑的早期学习卡带中就带有LOGO语言:
在LOGO语言中,使用一些非常简单的命令,就能够绘制出非常漂亮的图案。比如,执行以下指令:
这段指令的意思是,让小海龟向前爬行100步,然后向右旋转144度,以此重复5次,就画出了一颗五角星。有关LOGO语言的详细介绍,可以参考百度百科相关介绍。
出于兴趣以及对童年的回忆,我使用C#语言,基于Irony语法解析器生成框架,实现了LOGO语言的语法解析和执行系统:LogoSharp。于是,我可以在自己的应用程序中使用LogoSharp来实现LOGO程序的执行,并控制海龟实现图形绘制:
LogoSharp基于MIT协议开源,地址是:https://github.com/daxnet/logo-sharp。我也将其封装成NuGet包,可以在.NET Framework以及.NET Core下直接使用。首先,将LogoSharp NuGet包添加到自己的项目中,注意,目前是Preview的版本,所以,如果使用Visual Studio中的NuGet界面,需要勾选Include prerelease的复选框。如果使用Package Manager Console,那只要敲入命令就行了:
1 |
|
然后,在你的应用程序中使用LogoSharp:
1 2 3 4 5 6 7 |
|
LogoSharp开发框架本身是基于事件的,也就是,只要有控制小海龟动作的指令被执行,就会产生一个对应的事件,比如上面的代码中,执行FD 102指令时,就会产生一个Forward事件,表示此时需要让小海龟向前走102步,在这个演示代码中,Forward事件处理函数就会将前进步数输出到控制台。
在LogoSharp的源代码中,有一个测试程序,就是上面动图所演示的这个程序,它是一个Windows Forms的应用程序,它就是订阅了LogoSharp产生的事件,然后控制小海龟的运动,并通过GDI+在指定的窗体上绘制图形。
目前,LogoSharp支持以下功能:
语言特性
- 变量的定义与使用
- MAKE指令
- 局部变量与全局变量
- 表达式
- 一元表达式(Unary Expression)
- 二元表达式(Binary Expression)
- 常量表达式(Constant Expression)
- 函数调用表达式(Function Call Expression)
- 过程(TO … END程序结构)
- 函数调用
- 平方根函数(SQRT)
- 随机函数(RANDOM)
- 内联注释行,使用分号(;)作为注释起始符
基本行为控制命令
- PENDOWN/PD:下笔,此时移动海龟,会进行线段绘制
- PENUP/PU:提笔,此时移动海龟,不会进行绘制
- SETPENCOLOR/SETPC/PC:设置线条的颜色
- SETPENSIZE:设置线条的粗细
- PENERASE/PE:设置下笔行为为擦除行为
- PENNORMAL/PN:设置下笔行为为绘制行为
基本绘制命令
- LEFT/LT:向左旋转
- RIGHT/RT:向右旋转
- FORWARD/FD:向前步进
- BACKWARD/BK/BACK:向后倒退
- DELAY:海龟行为间隔延迟,单位:毫秒
- DRAW/CLS/CLEARSCR/CLEARSCREEN/CS:清除屏幕内容
海龟控制命令
- HOME:海龟归位到屏幕中心
- SHOWTURTLE/ST:将海龟显示在屏幕上
- HIDETURTLE/HT:将海龟隐藏起来
流程控制命令
- REPEAT:重复执行,支持RepCount内部参数,用于指代当前的迭代数
目前LogoSharp还有很多可以完善的地方:
- IF/WHILE语句暂不支持,但很快会支持
- 目前不支持一条语句分行编写,造成的结果是,有可能一条语句会写得很长
- 除了上面列表中的命令,其它命令暂不支持,不过今后也会陆续加入
- 不支持布尔值和布尔表达式以及逻辑操作
- 内置函数调用需要用花括号括起来,比如:{SQRT 2}。主要是因为函数调用本身是表达式,而其参数列表也是表达式,那么,如果不用括号这样的界定符括起来,语法上就会出现二义性。比如:hello world 2,你可以说hello是调用函数的函数名,它有两个参数:world和2,也可以说hello是一个没有参数的函数调用,而world是另一个函数,它的参数为2
此外,今后也会加入更多的内建函数,并使得函数扩展更为方便。
LogoSharp是一个非常有趣的项目,今后我会进一步做一些扩展,比如丰富函数库以及提供更好的编程环境等。后续我也会介绍一些有关Irony语法解析器生成框架的内容,以及LogoSharp实现中遇到的一些有趣的问题及其解决办法。