本项目旨在重现「木兰」编程语言的语法和功能,已开源在码云。所有例程演示的语法可用原始的木兰可执行文件 ulang-0.2.2.exe 检验。如发现有异烦请告知,定将礼谢。
前两天用木兰调用 pygame 库实现了个井字棋棋盘界面。期间遇到了一些问题,先小结一下。
注:解决方法限于个人至今对木兰和 Python 的了解。如有高招,烦请指教!
python 中很常用的结构,可以如下初始化:
>>> t = (1,2)
>>> t
(1, 2)
>>> t = 2, 3
>>> t
(2, 3)
但木兰中好像没找到类似的简便方法。幸好与 python 相似,函数返回多项时就会打包成元组,因此暂时这样定义函数:
func 多项2(a, b) {
return a, b
}
func 多项3(a, b, c) {
return a, b, c
}
...
之后支持变长参数时,就可以合并为一个函数了。
下面是 pygame 的常见操作,检查 pygame.event 的 type:
for event in pygame.event.get():
if event.type == pygame.QUIT :
但木兰中的 type 是类型定义的关键词,因而如果仍使用 .type 会报错。刚遇到这一问题时,颇为震惊,以为发现了木兰的一个大硬伤,不过还好 python 还有一个 __getattribute__('type')
可用。但另一种方法用在这里就无法获得 type 值:
func getType(个体) {
for 属性, 值 in 个体.__dict__.items() {
return 值 if 属性 == 'type'
}
}
大概因为这个 type 是个 @property(木兰中的应变属性),那么如果是普通属性如下:
type 人 {
func $人(名) {
$type = 名
}
}
上面两种方法就都可用。
python 中判断字典是否包含某键,推荐使用“键 in 字典”,集合也类似。木兰中的 in 关键词并不支持这种操作,也没找到其他语法支持。现在只找到调用 __contains__()
这一方式。
python 的字符串插值功能比如“f'{行号}.0'”可以简化字符串拼接。这几天重现了木兰的类似功能,如下对比,比拼接方式简洁不少:
"[" + $词性 + " 行:" + str($行) + " 列:" + str($起) + "~" + str($止) + "], 内容: " + $内容 // 拼接
"[`$词性` 行:`$行` 列:`$起`~`$止`], 内容: `$内容`" // 插值
除了"`表达式`"格式,木兰还支持“\(表达式\)”格式。至于为何支持两种格式,暂时想到的一种使用场景是带有“`”字符的字符串插值,比如 “`a某变量b”,那么“某变量”就可以用“\(\)”:
a = 3
print("`a\(a\)a") => `a3a
print("`a`a`a") => 3a`a
这有个实现细节的困惑。在插值的语法树节点创建时,使用的是 ast.Mod() 运算符。但这不是求余操作么?这个 Mod 有详细说明文档吗?
主要部分的代码行数统计,格式为:上次->现在。
编辑器
,实现与测试都是木兰代码:333分析器/语法分析器.py
:958 -> 986分析器/词法分析器.py
:198测试/运行所有.py
,检验所有木兰测试代码片段:185环境.py
,定义全局方法:157分析器/语法成分.py
,从语法分析器中提取出来的枚举常量:79分析器/语法树.py
:178交互.py
,交互环境(REPL):138功用/反馈信息.py
:49中.py
,主程序:41分析器/错误.py
:17测试/unittest/语法树.py
,确保生成的语法树与原始版本一致:67测试/unittest/交互.py
,交互环境相关测试:28