Arbiter Script Syntax¶
Arbiter scripts use the same Platypus language syntax as Pipeline.
Identifiers and Keywords¶
Identifiers¶
Identifiers are used to identify objects and can represent variables, functions, etc. Identifiers include keywords; custom identifiers cannot duplicate keywords.
Identifiers consist of numbers (0-9
), letters (A-Z a-z
), and underscores (_
), but cannot start with a number and are case-sensitive. For example:
_abc
abc
abc1
abc_1_
If an identifier needs to start with a non-letter or non-underscore character, or contains special characters, it must be enclosed in backticks, such as:
1abc
@some-variable
这是一个表情包变量👍
Keywords¶
Keywords are words with special meanings, such as if
, elif
, else
, for
, in
, break
, continue
, nil
, etc., and cannot be used as variable names, constant names, or function names.
Comments¶
Use #
as the line comment symbol; inline comments are not supported. For example:
# This is a line comment
a = 1 # This is a line comment
"""
This is a (multi-line) string, used as a comment
"""
a = 2
"String"
a = 3
Built-in Data Types¶
The value of a variable can change dynamically, but each value has a clear data type, which is divided into Basic Types and Composite Types.
Basic Types¶
Integer (int) Type¶
The integer type is a 64-bit signed integer, currently only supporting decimal representation, such as -1
, 0
, 1
, +19
.
Float (float) Type¶
The float type is a 64-bit signed floating-point number, currently only supporting decimal representation, such as -1.00001
, 0.0
, 1.0
, +19.0
.
Boolean (bool) Type¶
The boolean type has only two values: true
and false
.
String (str) Type¶
Strings can be defined with double or single quotes, and multi-line strings can be enclosed in triple double or single quotes, for example:
"hello world"
'hello world'
- Use
"""
to express multi-line strings
- Use
'''
to express multi-line strings
Composite Types¶
Composite types include map
and list
, which are reference types. Multiple variables can point to the same object, and no memory copy is performed during assignment.
Map Type¶
map
is a key-value pair structure, where keys can only be strings, and values can be of any type. Elements are read and written through index expressions, for example:
a = {
"1": [1, "2", 3, nil],
"2": 1.1,
"abc": nil,
"def": true
}
# Since a["1"] is a list object, b only references the value of a["1"]
b = a["1"]
"""
Now a["1"][0] == 1.1
"""
b[0] = 1.1
List Type¶
list
can store any number of values of any type, and elements are read and written through index expressions, for example:
Operators¶
Platypus supports the following operators, listed in order of precedence from lowest to highest:
Precedence | Symbol | Associativity | Description |
---|---|---|---|
1 | `=` | Right | Assignment; named parameters; lowest precedence |
1 | `+=` | Right | Assignment, left operand = left operand + right operand |
1 | `-=` | Right | Assignment, left operand = left operand - right operand |
1 | `*=` | Right | Assignment, left operand = left operand * right operand |
1 | `/=` | Right | Assignment, left operand = left operand / right operand |
1 | `%=` | Right | Assignment, left operand = left operand % right operand |
2 | `||` | Left | Logical "OR" |
3 | `&&` | Left | Logical "AND" |
4 | `in` | Left | Check if key is in map; check if element is in list; check if substring is in string |
5 | `>=` | Left | Condition "greater than or equal to" |
5 | `>` | Left | Condition "greater than" |
5 | `!=` | Left | Condition "not equal to" |
5 | `==` | Left | Condition "equal to" |
5 | `<=` | Left | Condition "less than or equal to" |
5 | `<` | Left | Condition "less than" |
6 | `+` | Left | Arithmetic "addition" |
6 | `-` | Left | Arithmetic "subtraction" |
7 | `*` | Left | Arithmetic "multiplication" |
7 | `/` | Left | Arithmetic "division" |
7 | `%` | Left | Arithmetic "modulus" |
8 | `!` | Right | Unary operator; logical "negation", can be used with the 6 built-in data types |
8 | `+` | Right | Unary operator; positive sign, can be used to represent positive numbers |
8 | `-` | Right | Unary operator; negative sign, used to flip the sign or represent negative numbers |
9 | `[]` | Left | Subscript operator; can use list index or map key to get values |
9 | `()` | Left | Can change operator precedence; function call |
Expressions¶
Platypus uses the comma ,
as the expression separator. Expressions can have values, while statements do not have values.
Literal Expressions¶
Literal values of various data types are expressions, such as integers 100
, -1
, 0
, floats 1.1
, boolean values true
, false
, etc.
Literal expressions for composite types are as follows:
- List literal expressions
- Map literal expressions
Call Expressions¶
The following is a function call to get the number of elements in a list:
Binary Expressions¶
Binary expressions consist of a binary operator and left and right operands.
In the current version, assignment expressions are considered binary expressions and have return values; however, since assignment expressions may cause issues, this syntax will be removed in the future, and assignment statements will be added instead.
# 0
2 / 5
# 0.4, the type of the left operand is promoted to float during calculation
2 / 5.0
# true
1 + 2 * 3 == 7 && 1 <= 2
# Due to the right associativity of the `=` operator, a = (b = 3), a == 3
b == 3;
a = b = 3
# Note: Since the assignment expression syntax will be deprecated, please replace it with assignment statements
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
Index Expressions¶
Use the []
subscript operator to manipulate elements of list
or map
.
You can use index expressions to get or modify elements of list
or map
, or add elements to map
.
For lists, negative indices can be used.
Syntax Example:
a = [1, 2 ,3, -1.]
b = {"a": [-1], "b": 2}
a[-1] = -2
b["a"][-1] = a[-1]
# Result
# a: [1,2,3,-2]
# b: {"a":[-2],"b":2}
Parentheses Expressions¶
Parentheses expressions can change the precedence of operands in binary expressions but cannot change associativity:
Statements¶
All expressions in Platypus can be considered value statements. When an expression ends with the statement separator ;
or \n
, it is considered a statement. For example, the following script contains four statements:
Value Statements (Expression Statements)¶
An expression followed by a statement separator can be considered a value statement. The following are four valid statements:
# Float as a statement
1.;
# Function call expression as a statement
len("Hello World!"); len({"a": 1})
# Identifier as a statement
abc
Assignment Statements¶
Syntax Example:
key_a = "key-a"
# Identifier a as the left operand, assigning a list literal to a
a = [1, nil, 3]
# Index expression as the left operand
a[0] = 0
a[2] = {"key-b": "value-b"}
a[2][key_a] = 123
Conditional Statements¶
Similar to most programming languages, depending on whether the condition of if/elif
is met, the corresponding block of statements is executed. If none are met, the else
branch is executed.
Currently, condition
can be any expression, as long as its value is one of the built-in data types. When the value is the default value of the type, the expression value is false
:
- When the condition is of type
int
, if it is0
, the condition isfalse
; otherwise, it istrue
- When the condition is of type
float
, if it is0.0
, the condition isfalse
; otherwise, it istrue
- When the condition is of type
string
, if it is an empty string""
, the condition isfalse
; otherwise, it istrue
- When the condition is of type
bool
, the condition is the current value - When the condition is of type
nil
, the condition isfalse
- When the condition is of type
map
, if its length is 0, the condition isfalse
; otherwise, it istrue
- When the condition is of type
list
, if its length is 0, the condition isfalse
; otherwise, it istrue
Loop Statements¶
Platypus supports for
statements and for in
statements.
The following are two statements that can only be used within loop statement blocks:
continue
statement, skips the remaining statements and continues to the next iterationbreak
statement, ends the loop
Using for
statements may cause infinite loops, so they should be used with caution, or for in
statements should be used instead whenever possible.
Usage Examples:
- Using
for
to execute a loop 10 times:
- Using
for in
to iterate over all elements of alist
:
- Using
for in
to iterate over all keys of amap
:
- Using
for in
to iterate over all characters of astring
: