仓库源文

本项目旨在重现「木兰」编程语言的语法和功能,已开源在码云。所有例程演示的语法可用原始的木兰可执行文件 ulang-0.2.2.exe 检验。如发现有异烦请告知,定将礼谢

前两天用木兰调用 pygame 库实现了个井字棋棋盘界面。期间遇到了一些问题,先小结一下。

1 生态兼容问题

注:解决方法限于个人至今对木兰和 Python 的了解。如有高招,烦请指教!

1.1 元组 (tuple)

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
}
...

之后支持变长参数时,就可以合并为一个函数了。

1.2 如何引用 type 属性

下面是 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 = 名
    }
}

上面两种方法就都可用。

1.3 键 in 字典

python 中判断字典是否包含某键,推荐使用“键 in 字典”,集合也类似。木兰中的 in 关键词并不支持这种操作,也没找到其他语法支持。现在只找到调用 __contains__() 这一方式。

2 本周重现功能:字符串插值

python 的字符串插值功能比如“f'{行号}.0'”可以简化字符串拼接。这几天重现了木兰的类似功能,如下对比,比拼接方式简洁不少:

"[" + $词性 + " 行:" + str($行) + " 列:" + str($起) + "~" + str($止) + "], 内容: " + $内容  // 拼接

"[`$词性` 行:`$行` 列:`$起`~`$止`], 内容: `$内容`"  // 插值

除了"`表达式`"格式,木兰还支持“\(表达式\)”格式。至于为何支持两种格式,暂时想到的一种使用场景是带有“`”字符的字符串插值,比如 “`a某变量b”,那么“某变量”就可以用“\(\)”:

a = 3
print("`a\(a\)a") => `a3a
print("`a`a`a") => 3a`a

这有个实现细节的困惑。在插值的语法树节点创建时,使用的是 ast.Mod() 运算符。但这不是求余操作么?这个 Mod 有详细说明文档吗?


附录:代码量统计

主要部分的代码行数统计,格式为:上次->现在。