结构
[说明]
[$语句]
[说明]
出于做项目和写简化版游戏王类似游戏的需要,要写一个脚本语言的解释器。
这个脚本的理念:
- 这个脚本语言只定义逻辑,下面会看到,具体功能由具体解释器提供
- 只要满足一定条件,就会执行一些东西,它不完全是顺序执行的
- 基本概念只有两个,“命令”和“历史”
- 所有的语句都是执行命令。
- 如果一个形如%expression%的历史被设置,那么所有与%expression%相关联的命令都会被执行,设置历史本身是一个命令。
- 如果把正则表达式类似的匹配式子当作函数调用来看,匹配项就是函数的参数。
就这么简单。
-----------------
[$语句]
解释器应该保留一个默认命令,"_$", 只有这个命令这个不能被重定义。
推荐写成"$",并重定义"$"的各种功能,以后我们会看到如何重定义"$"的功能。
以汉诺塔问题为例举个例子
假定具体解释器已经定义下述内容, ,定义它们的一种可能方式是通过重写各个功能的历史关联表达式:
$ "Expression" history to "Name":
功能是使形如Expression的历史与"Name"对应的命令相关联
也就是:一旦出现了形如Expression的历史,名为"Name"的命令就会被执行
$ "Name" command as :
定义一个命令
$ "String" history :
把String写入历史
如果有关联命令,会按照后关联先执行的顺序依次执行
$ "varname" = "value":
把变量设为某个表达式或值
$ "$_output" = "value"
把value的值输出
_break "condition"
系统功能,如果条件condition满足,直接跳出命令
同时要说明的是,语句不一定预定义好,比方说赋值的语句,可以用下面的比较曲折的方式在程序中定义
_$ "$ %varname = %value" history to command as
{
$ "_$ $1 = $2" history
}
这里面%varname 和 %value 分别用变量名和值的模式来替换
或者干脆
_$ "%varname = %value" history to command as
{
$ "_$ $1 = $2"
}
那么给$a赋值为5的写法可以是
a = 5
这就和常见的形式类似了
$1 $2...$n 对应匹配的第n项
汉诺塔脚本是:
$ "%d %c %c %c" history to "hanoi"
$ "hanoi" command as
{
_break $1<=0
$ "n" = $1-1
$ "$n $2 $4 $3" history
$ "$_output" = "$2->$4\n"
$ "$n $3 $2 $4" history
}
要运行这个脚本解决规模为3的汉诺塔问题
输入
hanoi 3 A B C
叫做直接执行命令
或者(如果输入也当作历史来看)
3 A B C
叫做(通过设置历史)触发执行命令
事实上hanoi命令的递归执行部分,就是采用了后面这种方式
如果你对这个有兴趣,你会在下一篇日志看到关于这个语言的一个形象的比喻(也许还有我做的一个很粗糙的解释器下载)