(本章基本完成)
Dinpy提供了丰富的语句,有些语句是传统语言常见的,比如iff, when_loop, each_loop等(为避免与python关键字冲突,语句关键字有所不同)。有些语句是lisp系列语言所独有的。比如block/exit, catch/throw,protect/always等。本章将介绍如何使用这些语句。
后面的文字中,为了说明语句的格式,引入一些约定:
- {{ }}
- 表示分组。
- << >>
- 表示其中的内容是可选的,可以出现一次或者不出现。
- ...
- 表示前面的项可以重复任意次,包括0次。
- !...
- 表示前面的项重复一次以上。
例如,语句... 表示逗号分隔的语句列表。
顺序执行语句(do语句)。
格式: do[ 语句... ]
>>> do[i<<0, prin(i), prin(' '), ++i]
0 1
do 后面跟随一组语句序列,用中括号括起来,形成顺序执行语句。依据python分隔表达式的要求,语句和语句之间以逗号隔开。
变量绑定语句(let语句)。 格式: let ( {{变量<<值}}... ) . do[ 语句... ]
>>> let(i << 1).do[ i ]
1
递归绑定语句(letr语句)。 格式: letr ( {{变量<<值}}... ) . do[ 语句... ]
>>> letr(f << fun(x)[ iff(x==1) .do[ 1 ] .els[ x+f(x-1) ] ]) .do [f(4)]
10
条件分支语句(iff语句)
格式: iff(条件).do[ 语句... ] {{ .elsif(条件).do[ 语句... ] }}... << .els[ 语句... ] >>
从iff开始,依次测试iff和每个elsif分支的条件,如果条件为真,则执行随后对应的do块,如果所有的条件都为假,并且存在els块,则执行els块中的语句。
可以看到,dinpy选用的都是不与python的if-elif-else冲突的关键字。
上述格式说明中,为了方便,{{}}表示分组,... 表示前面的内容可以重复任意次,包括0次。 << ... >>>表示其中的内容是可选项,可以出现,也可以不出现。后面对此不知一一说明。
>>> iff(0).do[1] .elsif(1).do[2] .els[3]
2
>>> iff(0).do[1] .elsif(0).do[2] .els[3]
3
分情况语句(case语句)。
格式: case(表达式) {{.of(值...)[ 语句... ]}}... << .els[ 语句... ] >>
先对case后的表达式求值,看值包含在哪一个of后面的值列表之中,选择执行对应的语句列表。如果表达式的值不包含在任何一个of后的值列表中,则执行els后面的语句列表。
>>> x
x
>>> case(x).of(1)[prin(1)].of(2,3)[prin(4)].els[prin(5)]
5
>>> x<<3
3
>>> case(x).of(x)[prin(1), 1].of(2)[prin(2), 2].els[prin(3), 3]]
3
>>> case(x).of(1)[prin(1), 1].of(2)[prin(2), 2].els[prin(3), 3]]
1
>>> x<<(1,2)
(1, 2)
>>> case(x).of((1,2), (3,4))[prin((1,2),(3,4))].of((2,3))[prin((2,3))].els[prin('others')]
(1, 2) (3, 4)
我们看到,最后一个例子的case表达式是个元组。case表达式可以是整数以外类型的数据。只要表达式的值可以作为python dict的键,就可以用在case语句中。
块语句(block语句)。格式:block.name[语句...]
>>> block.name[ prin(1), prin(2)]
1 2
退出语句(exit语句)。
格式:exit {{ <<.label>> | {{ << /type >> << *level >> }} }} << ‘>>’ 返回值 >>
退出块语句或循环语句。可以用exit.type*level的格式指定从哪种循环退出,要退出几层。type是’when’,’times’, ‘until’或者’each’等。如果level省略,则只退出包含该exit语句的最内层循环。也可以用exit.label的格式指定所要退出的块语句或循环语句的标号。如果type和label都省略,则退出所有类型循环的指定层或最内层语句块。exit >> value 表达式将指定返回的值。如果省略,默认返回None。
>>> block.a[ prin(1), exit.a, prin(2) ]
1
重做语句(next语句)。
格式:next << .label >> | {{ << /type >> << *level >>}}
重做块语句或循环语句。可以用next.type*level的格式指定从哪种循环退出,要退出几层。type是’loop’(无限循环),’when’(when-loop或loop-when循环),’times’(loop-times循环), ‘until’(loop-until循环)或者’each’(each循环)等。如果level省略,则只重做包含该next语句的最内层循环。也可以用next.label的格式指定所要重做的块语句或循环语句的标号。如果type和label都省略,则重做所有类型循环的指导层或最内层语句块。
>>> do [i<<0, block.a[ ++i, iff(i<3) .do [next.a] ], i ]
3
上面的例子说明,利用block, exit 和next语句可以构成循环。下一节将要介绍循环语句,而这些循环语句实际上正是利用block语句以及与exit和next对应的底层命令exit_block和continue_block构造的。
无限循环语句(loop语句)。
格式:loop[ 语句... ]
>>> i << 0
>>> loop [ prin(i), ++i, iff(i==3) .do[exit] ]
0 1 2
定数循环语句(loop-times语句)。
格式:loop(次数) [ 语句... ]
>>> loop(3)[ prin(i), --i ]
3 2 1
前置条件循环语句(when-loop语句)。
格式:when(条件).loop[ 语句... ]
>>> when(i!=0).loop[ prin(i), ++i]
0 1 2
后置条件循环语句(loop-when语句)。
格式:loop[ 语句... ].when(条件)
>>> loop [ prin(i), ++i].when(i<3)
0 1 2
直到型循环语句(loop-until语句)。
格式: loop[ 语句... ].until(条件)
>>> do[ i<<3, loop [ prin(i), --i ]. until(i==0)
3 2 1
遍历循环语句(each语句)。
格式:each(变量!...){{[表达式]!...}}.loop[ 语句... ]
将变量列表依次与所有范围组合成的元组列表中的每一项绑定。循环执行语句列表。表达式可以是slice类型的值,将转换为range。
>>> each(i)[0:3].loop[ prin(i) ]
0 1 2
循环标号语句(label语句)。
格式: label.name%loop语句
利用label语句,可以给上述循环语句设置标号。exit语句和next语句可以引用这个标号。
>>> label.outer%loop[
println('outer loop'),
i << 0,
label.inner%loop[
prin('inner loop: '),
println(i),
++i,
iff(i==3).do[ exit.outer >> 'exit from inner' ] ] ]
outer loop
inner loop: 0
inner loop: 1
inner loop: 2
'exit from inner'
这段程序利用exit.outer语句直接跳出外层循环, 并带回返回值’exit from inner’。
>>> loop[
println('outer loop'),
i << 0,
loop[
prin('inner loop: '),
println(i),
++i,
iff(i==3).do[ exit*2 >> 'exit from inner' ] ] ]
outer loop
inner loop: 0
inner loop: 1
inner loop: 2
'exit from inner'
这段程序利用exit*2语句直接跳出两层循环, 并带回返回值’exit from inner’。
(需要实例)
限定执行语句(on语句)。 格式:on( {变量<<表达式}!... ) .do [ 语句...]
catch 与 throw
捕获语句(catch语句)。
格式:catch(标记).do[语句...]
抛掷语句(throw语句)。
格式: throw(标记).do[语句...]
保护执行语句(protect语句)。
格式:protect[语句...].always[语句...]
python 异常语句(pytry语句)。# 尚未实现
格式:pytry[语句...].on(ExceptioinClass, e).do[语句...].final[语句...]
用pytry实现each-loop语句。