Arbiter 脚本语法¶
Arbiter 脚本采用与 Pipeline 相同的 Platypus 语言语法。
标识符与关键字¶
标识符¶
标识符用于标识对象,可以用来表示一个变量、函数等,标识符包含关键字;自定义的标识符不能与关键字重复。
标识符由数字 (0-9
)、字母 (A-Z a-z
)、下划线 (_
) 构成,但不能以数字开头,且区分大小写。例如:
_abc
abc
abc1
abc_1_
若标识符需以非字母或非下划线开头,或包含特殊字符,需用反引号括起来,如:
1abc
@some-variable
这是一个表情包变量👍
关键字¶
关键字是具有特殊意义的单词,如 if
, elif
, else
, for
, in
, break
, continue
, nil
等,不能用作变量名、常量名或函数名。
注释¶
使用 #
作为行注释符号,不支持行内注释。例如:
内置数据类型¶
变量的值可以动态变化,但每个值都有明确的数据类型,分为基本类型和复合类型。
基本类型¶
整数(int)类型¶
整型为 64 位有符号整数,目前仅支持十进制表示,如 -1
, 0
, 1
, +19
。
浮点(float)类型¶
浮点型为 64 位有符号浮点数,目前仅支持十进制表示,如 -1.00001
, 0.0
, 1.0
, +19.0
。
布尔(bool)类型¶
布尔类型只有两个值:true
和 false
。
字符串(str)类型¶
字符串可以用双引号或单引号定义,多行字符串可以用三双引号或三单引号括起来,例如:
"hello world"
'hello world'
- 使用
"""
表达多行字符串
- 使用
'''
表达多行字符串
复合类型¶
复合类型包括 map
和 list
,它们是引用类型,多个变量可以指向同一个对象,赋值时不进行内存拷贝。
Map 类型¶
map
是键值对结构,键只能是字符串类型,值可以是任意类型。通过索引表达式读写元素,例如:
a = {
"1": [1, "2", 3, nil],
"2": 1.1,
"abc": nil,
"def": true
}
# 由于 a["1"] 是 list 对象,此时 b 只是引用了 a["1"] 的值
b = a["1"]
"""
此时 a["1"][0] == 1.1
"""
b[0] = 1.1
List 类型¶
list
可以存储任意数量、任意类型的值,通过索引表达式读写元素,例如:
运算符¶
Platypus 支持以下运算符,优先级从低到高:
优先级 | 符号 | 结合性 | 描述 |
---|---|---|---|
1 | `=` | 右 | 赋值;命名参数;优先级最低 |
1 | `+=` | 右 | 赋值,左操作数 = 左操作数 + 右操作数 |
1 | `-=` | 右 | 赋值,左操作数 = 左操作数 - 右操作数 |
1 | `*=` | 右 | 赋值,左操作数 = 左操作数 * 右操作数 |
1 | `/=` | 右 | 赋值,左操作数 = 左操作数 / 右操作数 |
1 | `%=` | 右 | 赋值,左操作数 = 左操作数 % 右操作数 |
2 | `||` | 左 | 逻辑“或” |
3 | `&&` | 左 | 逻辑“与” |
4 | `in` | 左 | 判断 key 在 map 中;指定元素在 list 中;子字符串被包含在字符串中 |
5 | `>=` | 左 | 条件“大于等于” |
5 | `>` | 左 | 条件“大于” |
5 | `!=` | 左 | 条件“不等于” |
5 | `==` | 左 | 条件“等于” |
5 | `<=` | 左 | 条件“小于等于” |
5 | `<` | 左 | 条件“小于” |
6 | `+` | 左 | 算术“加” |
6 | `-` | 左 | 算术“减” |
7 | `*` | 左 | 算术“乘” |
7 | `/` | 左 | 算术“除” |
7 | `%` | 左 | 算术“取余数” |
8 | `!` | 右 | 一元运算符;逻辑“取反”,可用于内置的 6 种数据类型 |
8 | `+` | 右 | 一元运算符;正号,可用于表示正数 |
8 | `-` | 右 | 一元运算符;负号,用于翻转符号、表示负数 |
9 | `[]` | 左 | 下标运算符;可使用 list 下标或 map 的键取值 |
9 | `()` | 左 | 可改变运算符优先级;函数调用 |
表达式¶
Platypus 使用逗号 ,
作为表达式分隔符,表达式可以有值,而语句没有值。
字面量表达式¶
各种数据类型的字面量都是表达式,如整数 100
, -1
, 0
, 浮点数 1.1
,布尔值 true
, false
等。
复合类型的字面量表达式如下:
- List 字面量表达式
- Map 字面量表达式
调用表达式¶
以下为一个函数调用,用于取列表元素个数:
二元表达式¶
二元表达式由二元运算符和左右操作数构成。
当前版本赋值表达式属于二元表达式,其有返回值;但由于赋值表达式可能造成一些问题,后续将会删除该语法,并增加赋值语句语法。
# 0
2 / 5
# 0.4,计算时将左操作数的类型提升至浮点数
2 / 5.0
# true
1 + 2 * 3 == 7 && 1 <= 2
# 由于 `=` 运算符的右结合性,a = (b = 3), a == 3
b == 3;
a = b = 3
# 注意:由于赋值表达式语法即将废除,请替换为赋值语句
b = 3
a = b
"a" in [1,"a"] # true
"def" in "abcdef" # true
"a" in {"a": 1} # true
"b" in {"a": 1} # false
x = 1; y= [1]
x in y # true
索引表达式¶
使用 []
下标运算符来对 list
或 map
的元素进行操作。
可以通过索引表达式对 list
或 map
的元素进行取值或修改以及往 map
中添加元素。
对于列表,可以使用负数进行索引。
语法示例:
a = [1, 2 ,3, -1.]
b = {"a": [-1], "b": 2}
a[-1] = -2
b["a"][-1] = a[-1]
# 结果
# a: [1,2,3,-2]
# b: {"a":[-2],"b":2}
括号表达式¶
括号表达式可以改变二元表达式中的操作数运算优先级,但不能改变结合性:
语句¶
Platypus 所有的表达式可以视为值语句,当表达式以语句分隔符号 ;
或 \n
结束时,其将被视为一个语句,如以下脚本内容包含四个语句:
值语句(表达式语句)¶
表达式后面跟语句分隔符号时可视为值语句,以下为四个合法的语句:
赋值语句¶
语法示例:
key_a = "key-a"
# 标识符 a 作为左操作数,赋予 a 一个列表字面量
a = [1, nil, 3]
# 索引表达式作为左操作数
a[0] = 0
a[2] = {"key-b": "value-b"}
a[2][key_a] = 123
条件语句¶
与大多数编程语言相同,根据 if/elif
的条件是否成立,进入对应的语句块中,若都不成立则进入 else
分支。
当前 condition
可以是任意表达式,只要其值为内置数据类型之一,当其值为类型默认值时表达式值为 flase
:
- 当条件为
int
类型值时,其为0
则条件为false
,否则为true
- 当条件为
float
类型值时,其为0.0
则条件为false
,否则为true
- 当条件为
string
类型值时,其为空字符串""
则条件为false
,否则为true
- 当条件为
bool
类型值时,条件为当前值 - 当条件为
nil
类型值时,条件为false
- 当条件为
map
类型值时,其长度为 0 则条件为false
,否则为true
- 当条件为
list
类型值时,其长度为 0 则条件为false
,否则为true
循环语句¶
Platypus 支持 for
语句和 for in
语句。
以下为两个只允许在循环语句块中使用的语句:
cotinue
语句,不再执行后续语句,继续开始下一次循环break
语句,结束循环
使用 for
语句时可能造成无限循环,应谨慎使用,或尽可能使用 for in
语句替代。
使用示例:
- 使用
for
执行 10 次循环:
- 使用
for in
遍历list
的所有元素:
- 使用
for in
遍历map
的所有键:
- 使用
for in
遍历string
的所有字符: