Platypus Grammar¶
Below is the syntax definition for the Platypus language used by the Pipeline processor. With the gradual support of different syntaxes, this document will be adjusted and added or deleted to varying degrees.
Identifier and Keyword¶
Identifier¶
Identifiers are used to identify objects and can be used to represent a variable, function, etc. The identifier contains keywords; the custom identifier cannot be repeated with the keywords of the Pipeline data processor language;
Identifiers can be composed of numbers (0-9
), letters (A-Z a-z
), and underscores (_
), but the first character cannot be a number and is case-sensitive:
_abc
abc
abc1
abc_1_
Use backticks if you need to start with a non-alphabet or non-underscore, or use characters other than the above in the identifier:
`1abc`
`@some-variable`
` 这是一个表情包变量👍`
special agreement:
We agree to use the identifier _
to represent the input data of the Pipeline data processor, and this parameter may be implicitly passed to some built-in functions;
To maintain forward compatibility, _
will be treated as an alias for message
when used in the current version.
Keyword¶
Keywords are words with special meaning, such as if
, elif
, else
, for
, in
, break
, continue
, nil
, etc. These words cannot be used as variables or constants or the name of a function etc.
Comments¶
Use #
as line comment character, inline comment is not supported
# This is a line comment
a = 1 # this is a comment line
"""
This is a (multiline) string that replaces comments
"""
a = 2
"comments"
a = 3
Built-in Data Types¶
In Platypus, the Pipeline data processor language, by default, the type of the value of a variable can change dynamically, but each value has its data type, which can be one of the basic types or composite type
When a variable is not assigned a value, its value is nil, which means no value.
Basic Type¶
Integer (int) Type¶
Integer type length is 64bit, signed, currently only supports writing integer literals in decimal format, such as -1
, 0
, 1
, +19
Floating Point (float) Type¶
The length of the floating-point type is 64bit, signed, and currently only supports writing floating-point literals in decimal, such as -1.00001
, 0.0
, 1.0
, +19.0
Boolean (bool) Type¶
Boolean literals only have true
and false
String (str) Type¶
String literals can be written with double quotes or single quotes, and multi-line strings can be written using triple double quotes or triple single quotes
"hello world"
'hello world'
- Use
"""
to express multi-line strings
- Use
'''
to express multi-line strings
Composite Type¶
The map type and list type are different from other types. Multiple variables can point to the same map or list object. The memory copy of the list or map is not performed during assignment, but the memory address of the map/list value is referenced.
Map Type¶
The map type is a key-value structure. (Currently) only the string type can be used as a key, and the data type of the value is not limited.
It can read and write elements in the map through index expressions:
a = {
"1": [1, "2", 3, nil],
"2": 1.1,
"abc": nil,
"def": true
}
# Since a["1"] is a list object, b just refers to the value of a["1"]
b = a["1"]
"""
At this point a["1"][0] == 1.1
"""
b[0] = 1.1
List Type¶
The list type can store any number of values of any type in the list.
It can read and write elements in the list through index expressions:
Operator¶
The following operators are currently supported by Platypus, and the higher the value, the higher the priority:
Priority | Symbol | Associativity | Description |
---|---|---|---|
1 | = |
right | assignment; named argument; 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 | Determine whether the key is in the map; Specify the element in the list; The substring is included in the 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 "plus" |
6 | - |
left | arithmetic "minus" |
7 | * |
left | arithmetic "multiply" |
7 | / |
left | arithmetic "division" |
7 | % |
left | arithmetic "remainder" |
8 | ! |
right | unary operator; logical "negation", available for 6 built-in data types |
8 | + |
right | unary operator; positive sign, can be used to represent positive numbers |
8 | - |
right | unary operator; minus sign, used to flip the sign and represent negative numbers |
9 | [] |
left | Subscript operator; can use list subscript or map key to get value |
9 | () |
left | Can change operator precedence; function call |
Expression¶
Platypus uses the symbol comma ,
as the expression separator, such as the parameter transfer used to call the expression and the expression when the map and list are initialized.
In Platypus, expressions can have values, but statements must not have values, that is, statements cannot be used as the left and right operands of operators such as =
, but expressions can.
Literal Expression¶
Literals of various data types can be used as expressions, such as integers 100
, -1
, 0
, floating-point numbers 1.1
, Boolean values true
, false
, etc.
The following two are literal expressions of composite types:
- List literal expression
- Map literal expression
Call Expression¶
The following is a function call to get the number of list elements:
Binary Expression¶
Binary expressions consist of binary operators and left and right operands.
The current version of the assignment expression is a binary expression, which has a return value; but because the assignment expression may cause some problems, this syntax will be deleted in the future, and the assignment statement syntax will be added.
#0
2 out of 5
# 0.4, promote the type of the left operand to a floating-point number during calculation
2 / 5.0
#true
1 + 2 * 3 == 7 && 1 <= 2
# a = (b = 3), a == 3 due to the right associativity of the `=` operator
b == 3;
a = b = 3
# Note: Since the assignment expression syntax is about to be abolished, 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 Expression¶
Index expressions use the []
subscript operator to operate on the elements of a list/map.
The elements of list or map can be valued or modified and elements can be added to the map through index expressions. For lists, negative numbers can be used for indexing.
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}
Bracket Expression¶
Bracket expressions can change the precedence of operand operations in binary expressions, but not associativity:
Statement¶
All expressions in Platypus can be regarded as value statements. When an expression ends with a statement delimiter ;
or \n
, it will be regarded as a statement. For example, the following script contains four statements:
Value Statement (expression statement)¶
When an expression is followed by a statement delimiter, it can be regarded as a value statement. The following are four legal statements:
# floats as statements
1.;
# function call expression as statement
len("Hello World!"); len({"a": 1})
# identifiers as statements
abc
Assignment Statement¶
Syntax example:
key_a = "key-a"
# The identifier a is used as the left operand, assigning a a list literal
a = [1, nil, 3]
# index expression as left operand
a[0] = 0
a[2] = {"key-b": "value-b"}
a[2][key_a] = 123
Select Statement¶
Platypus supports if/elif/else
syntax:
Same as most programming languages, enter the corresponding statement block according to whether the condition of if/elif
is true, or enter the else branch if it is not true.
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, it is0
then the condition isfalse
, otherwise it istrue
- When the condition is a
float
type value, it is0.0
then the condition isfalse
, otherwise it istrue
- When the condition is a
string
type value, 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 value of type
nil
, the condition isfalse
- When the condition is a
map
type value, its length is 0 then the condition isfalse
, otherwise it istrue
- When the condition is a
list
type value, its length is 0 then the condition isfalse
, otherwise it istrue
Loop Statement¶
Platypus supports for
statement and for in
statement.
The following are two statements that are only allowed in a loop block:
cotinue
statement, do not execute subsequent statements, continue to start the next cycle- The
break
statement, which ends the loop
When using the for
statement, it may cause an infinite loop, so it should be used with caution, or use the for in
statement instead.
Example usage:
- Use
for
to execute 10 loops:
- Use
for in
to iterate over all elements of the list:
- use
for in
to iterate over all keys of the map:
- use
for in
to iterate over all characters of string: