Skip to content

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
"""hello
world"""
  • Using ''' for multi-line strings
'''
hello
world
'''

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:

a = [1, "2", 3.0, false, nil, {"a": 1}]

a = a[0] # a == 1

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
[1, true, "1", nil]
  • Map literal expressions
{
  "a": 1,
  "b": "2",
}

Call Expressions

The following is a function call used to get the number of elements in a list:

len([1, 3, "5"])

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:

# 1 + 2 * 3 == 7

(1 + 2) * 3  # == 9

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:

len("abc")
1
a = 2; a + 2 * 3 % 2

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.

if condition {

}
if condition {

} else {

}
if condition_1 {

} elif condition_2 {

} ... elif condition_n {

} else {

}

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 is 0 then the condition is false, otherwise it is true
  • When the condition is a float type value, if it is 0.0 then the condition is false, otherwise it is true
  • When the condition is a string type value, if it is an empty string "" then the condition is false, otherwise it is true
  • When the condition is a bool type value, the condition is the current value
  • When the condition is a nil type value, the condition is false
  • When the condition is a map type value, if its length is 0 then the condition is false, otherwise it is true
  • When the condition is a list type value, if its length is 0 then the condition is false, otherwise it is true

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 iteration
  • break 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.

for init-expr; condition; loop-expr {

}
for varb_name in map_value/list_value/string_value  {

}

Usage examples:

  • Use for to execute a loop 10 times:
for a = 0; a < 10; a = a + 1 {

}
  • Use for in to iterate over all elements of a list:
b = "2"
for a in ["1", "a" ,"2"] {
  b = b + a
  if b == "21a" {
    break
  }
}
# b == "21a"
  • Use for in to iterate over all keys of a map:
d = 0
map_a = {"a": 1, "b":2}
for x in map_a {
  d = d + map_a[x]
}
  • Use for in to iterate over all characters of a string:
s = ""
for c in "abcdef" {
  if s == "abc" {
    break
  } else {
    continue
  }
  s = s + "a"
}
# s == "abc"