中文编程
首发于中文编程

木兰编程语言基本功能摸索 (一)

早先 @yang leonier 摸索出部分[测试代码](zhihu.com/question/3665). 下面打算对木兰的各个基本功能进行逐步测试, 尽量用中文命名标识符(内置函数和关键字暂不打算汉化).

顺序参考标识符中文化后的[Python 3 官方入门文档](nobodxbodon.github.io/p) :)

顺便与 Python 运行结果作对比, 并加以记录.

运行环境见[前文](zhuanlan.zhihu.com/p/10)

懒得格式化了。直接上 md 格式。


### 数字

```python
> 2 + 2
4
> 50 - 5*6
20
> (50 - 5*6) / 4
5
> 8/5
1
```

与 Python 不同的是, 它的单杠除法是整除, 而不留小数点. 继续:

```python
> 17/3
5
> 17 // 3
17
> 17 // 好
17
> 17 % 3
2
> 5 * 3 + 2
17
```

看来它的双斜杠是注释. 还不知道小数除法怎么做, 待研究.

```python
> 5 ** 2
SyntaxError: File "<STDIN>", line 1:1, unexpected token "INTEGER_LITERAL"
5 ** 2
^
```

hmm, 乘方不是**, 待研究. 下面是变量赋值:

```python
> 宽 = 20
> 高 = 5 * 9
> 宽 * 高
900
```

变量不存在时, 与 Python 报错信息一样, 但是没有所在行数显示:

```python
> 数
NameError: name '数' is not defined
```

原来是这样, 只要有小数, 即判定为小数运算:
```
> 4 * 3.75 - 1
14.0
> 4/3.0
1.3333333333333333
```

几个发现:
- 不支持 python 中的_(上一个值)
- 与 python 一样, 显示小数返回值时, 会略去最后的 0
```
> 税率 = 12.5 / 100
> 价格 = 100.50
> 价格 * 税率
12.5625
> 价格 + _
NameError: name '_' is not defined
> 价格
100.5
> round(价格, 2)
100.5
> round(100.444, 1)
100.4
> round(100.444, 2)
100.44
```


### 字符串

很高兴看到支持中文字符串, 不用魔改了. 在输出显示上, 与 Python 不同的是, 略去了首尾的单双引号. 视觉上倒是比较清爽.

```python
> '数'

> 'spam eggs'
spam eggs
> 'doesn\'t'
doesn't
> "doesn't"
doesn't
> '"Yes," they said.'
"Yes," they said.
> "\"Yes,\" they said."
"Yes," they said.
> '"Isn\'t," they said.'
"Isn't," they said.
```

看来, 字符串的显示, 与 println 的效果相同(带换行), 对应 python 中的 print. 而 print 是不带换行的输出. 以后的测试打算用 println 替代python 中的 print 进行.

```python
> '"Isn\'t," they said.'
"Isn't," they said.
> print('"Isn\'t," they said.')
"Isn't," they said.> println('"Isn\'t," they said.')
"Isn't," they said.
> s = 'First line.\nSecond line.'
> s
First line.
Second line.
> print(s)
First line.
Second line.>
```

不支持在 python 中可以输出原始字符串(raw)的 r . 取代的是双反斜杠, 这个蛮接近其他编程语言的. 挺好.

```python
> println('C:\some\name')
C:\some
ame
> println(r'C:\some\name')
SyntaxError: File "<STDIN>", line 1:10, unexpected token "STRING_LITERAL_II"
println(r'C:\some\name')
^
> println('C:\some\\name')
C:\some\
ame
```

不知如何支持多行字符串, 待研究:

```python
> println("""\
>> 用途: 东西 [选项]
SyntaxError: File "<STDIN>", line 1:1, unknown token is found here
println("""\
^
> println("""""")
SyntaxError: File "<STDIN>", line 1:11, unexpected token "STRING_LITERAL"
println("""""")
^
> println("第" +
SyntaxError: File "<STDIN>", line 2:1, unexpected token "$end"

^
```

支持字乘和加:

```python
> 6 * '长' + '消'
长长长长长长消
> 6 * '长长' + '消'
长长长长长长长长长长长长消
```

不支持这样拼接:

```python
> '木' '兰'
SyntaxError: File "<STDIN>", line 1:5, unexpected token "STRING_LITERAL_II"
'木' '兰'
^
```

也不支持如下拼接:

```python
> '木' '兰'
SyntaxError: File "<STDIN>", line 1:5, unexpected token "STRING_LITERAL_II"
'木' '兰'
^
> 文本 = ('把多个字符串放在括号中'
SyntaxError: File "<STDIN>", line 2:1, unexpected token "$end"

^
> 前缀 = '木'
> 前缀 '兰'
SyntaxError: File "<STDIN>", line 1:4, unexpected token "STRING_LITERAL_II"
前缀 '兰'
^
```

下面和上面的拼接报错信息不同:

```python
> ('长' * 6) '消'
SyntaxError: File "<STDIN>", line 1:1, unexpected token "("
('长' * 6) '消'
^
> ('长' * 6)
长长长长长长
```

支持用 + 拼接:

```python
> 前缀 + '兰'
木兰
```

支持除了负索引之外的字符串截取方式:

```python
> 词 = '木兰编程语言'
> 词[0]

> 词[5]

> 词[-1]
TypeError: object of type 'int' has no len()
> 词[-6]
TypeError: object of type 'int' has no len()
> 词[0:2]
木兰
> 词[2:5]
编程语
> 词[:2] + 词[2:]
木兰编程语言
> 词[4:]
语言
> 词[-2:]
TypeError: object of type 'int' has no len()
```

超出范围的索引处理相同:

```python
> 词[42]
IndexError: string index out of range
> 词[4:42]
语言
> 词[42:]
```

字符串修改处理相同:

```python
> 词[0] = 'J'
TypeError: 'str' object does not support item assignment
> 词[2:] = 'py'
TypeError: 'str' object does not support item assignment
```

同样要用+拼接:

```python
> '花' + 词[1:]
花兰编程语言
> 词[:2] + '问好'
木兰问好
```

取长度相同:

```python
> 短语 = '迅雷不及掩耳之势'
> len(短语)
8
```

### 列表

列表赋值相同, 但与字符串类似, 不支持负索引.

```python
> 平方数 = [1, 4, 9, 16, 25]
> 平方数
[1, 4, 9, 16, 25]
> 平方数[0]
1
> 平方数[-1]
TypeError: object of type 'int' has no len()
> 平方数[-3:]
TypeError: object of type 'int' has no len()
```

下面这些列表操作结果基本一致:

```python
> 平方数[:]
[1, 4, 9, 16, 25]
> 平方数 + [36, 49, 64, 81, 100]
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
> 立方数 = [1, 8, 27, 65, 125]
> 立方数[3] = 64
> 立方数
[1, 8, 27, 64, 125]
> 立方数.append(216)
> 立方数.append(7 * 7 * 7)
> 立方数
[1, 8, 27, 64, 125, 216, 343]
> 字母 = ['a', 'b', 'c', 'd', 'e', 'f', 'g']
> 字母
[a, b, c, d, e, f, g]
> 字母[2:5] = ['C', 'D', 'E']
> 字母
[a, b, C, D, E, f, g]
> 字母[2:5] = []
> 字母
[a, b, f, g]
> 字母[:] = []
> 字母
[]
> 字母 = ['a', 'b', 'c', 'd']
> len(字母)
4
> 字母 = ['a', 'b', 'c']
> 数 = [1, 2, 3]
> 甲 = [字母, 数]
> 甲
[[a, b, c], [1, 2, 3]]
> 甲[0]
[a, b, c]
> 甲[0][1]
b
```

可惜没试出 while 的语法. 看lexer 里是有的. 待研究.

[待续]

发布于 2020-01-24

文章被以下专栏收录

    在所有编程语言和领域中尝试编写中文代码,开发相关工具,总结经验,一致代码风格。包括中文命名,汉化现有语言,创造中文语法的编程语言等等。作为最熟悉的母语,用来编写代码会让代码更容易被自己和母语相同的其他开发者理解。基于英文的编程语言和框架中,使用中文命名有时有技术问题。希望这里为后人趟雷,填坑。多数现有API是英文的,这里也会对其中一些常用的进行汉化。当然,这里也会对基于中文的编程语言进行探讨。包括汉化基于英文的编程语言,以及创造新的编程语言。