Arbiter Script Syntax¶
The Arbiter script uses 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 must not 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
This is an emoji variable pack👍
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 comment line
a = 1 # This is a comment line
"""
This is a (multi-line) string replacing comments
"""
a = 2
"String"
a = 3
Built-in Data Types¶
Variable values can dynamically change, but each value has a clear data type, divided into basic types and composite types.
Basic Types¶
Integer(int) Type¶
Integer is a 64-bit signed integer, currently only supporting decimal representation, such as -1
, 0
, 1
, +19
.
Float(float) Type¶
Float 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¶
Boolean type has only two values: true
and false
.
String(str) Type¶
Strings can be defined using double quotes or single quotes, and multi-line strings can be enclosed in triple double quotes or triple single quotes, for example:
"hello world"
'hello world'
- Using
"""
for multi-line strings
- Using
'''
for multi-line strings
Composite Types¶
Composite types include map
and list
; they are reference types, multiple variables can point to the same object without copying memory during assignment.
Map Type¶
map
is a key-value pair structure where keys can only be string types, and values can be any type. Elements are read and written via 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"]
"""
At this point `a["1"][0] == 1.1`
"""
b[0] = 1.1
List Type¶
list
can store any number of values of any type, elements are read and written via index expressions, for example:
Operators¶
Platypus supports the following operators, from lowest to highest precedence:
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 | Determines if key exists in map; if specified element is in list; if substring is included 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 "not", applicable to all six built-in data types |
8 | `+` | Right | Unary operator; positive sign, used to indicate positive numbers |
8 | `-` | Right | Unary operator; negative sign, used to reverse the sign, indicating negative numbers |
9 | `[]` | Left | Index operator; can use list indices or map keys to retrieve values |
9 | `()` | Left | Can change operator precedence; function calls |
Expressions¶
Platypus uses commas ,
as expression separators, expressions can have values, while statements do not have values.
Literal Expressions¶
Literals of various data types are expressions, such as integers 100
, -1
, 0
, floating-point numbers 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 used to get the number of elements in a list:
Binary Expressions¶
Binary expressions consist of binary operators and left and right operands.
In the current version, assignment expressions belong to binary expressions and have return values; however, due to potential issues with assignment expressions, this syntax will be removed later, and assignment statement syntax will be added.
# 0
2 / 5
# 0.4, when calculating, the type of the left operand is promoted to float
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 abolished soon, please replace it with an assignment statement
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 operate on elements of list
or map
.
Values or modifications can be made to list
or map
elements through index expressions, and elements can be added to map
. Negative numbers can be used for indexing in lists.
Syntax examples:
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}
Bracket Expressions¶
Bracket 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 a statement separator ;
or \n
, it is treated as a statement. For example, the following script content 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:
# Floating-point number as a statement
1.;
# Function call expression as a statement
len("Hello World!"); len({"a": 1})
# Identifier as a statement
abc
Assignment Statements¶
Syntax examples:
key_a = "key-a"
# Identifier `a` as the left operand, assigns 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 if/elif
condition holds, enter the corresponding statement block; if none hold, then enter the else
branch.
The current condition
can be any expression, as long as its value is one of the built-in data types, when its value is the default value of the type, the expression value is flase
:
- When the condition is an
int
type value, if it is0
then the condition isfalse
, otherwise it istrue
- When the condition is a
float
type value, if it is0.0
then the condition isfalse
, otherwise it istrue
- When the condition is a
string
type value, if it is an empty string""
then the condition isfalse
, otherwise it istrue
- When the condition is a
bool
type value, the condition is the current value - When the condition is a
nil
type value, the condition isfalse
- When the condition is a
map
type value, if its length is 0 then the condition isfalse
, otherwise it istrue
- When the condition is a
list
type value, if its length is 0 then 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:
cotinue
statement, does not execute subsequent statements, continues the next loop iterationbreak
statement, ends the loop
Using for
statements may cause infinite loops, so caution should be exercised, or for in
statements should be used as much as possible instead.
Usage examples:
- Use
for
to execute a loop 10 times:
- Use
for in
to iterate over all elements of alist
:
- Use
for in
to iterate over all keys of amap
:
- Use
for in
to iterate over all characters of astring
: