- 1. Assignments
- 2. Arithmetic operators
- 3. Comparison operators
- 4. Boolean Operators
- 5. Bitwise Operators
- 6. String Operators
- 7. Number Range operators
- 8. Collection Operators
- 9. Other operators
- 10. Operator Precedence
- 11. Operator Overloading
- 12. Acknowledgements
- 13. Legal Notice

SARL supports a collection of operators. Most of them are infix operators, and several are postfix operators.

The assignment operators are listed below. Local variables and fields can be assigned using the `=`

operator.
Compound assignment operators (`+=`

, `-=`

, `*=`

, `/=`

, and `%=`

) can be used as a shorthand for the assignment
of a binary expression. They work automatically when the corresponding infix operator is declared.

Operator | Operator Semantic |
---|---|

a = b | Set the variable a with the value of b. |

a += b | Alias to: `a = a + b` |

a -= b | Alias to: `a = a - b` |

a *= b | Alias to: `a = a * b` |

a /= b | Alias to: `a = a / b` |

a %= b | Alias to: `a = a % b` |

Note The assignment operator is the only one operator that cannot be overridden yet. See the operator overloading section for details.

The arithmetic operators are listed below and take numbers as operands. There are either unary (one operand) or binary (two operands).

Operator | Function Name | Operator Semantic |
---|---|---|

a + b | operator_plus | Add a and b. |

a - b | operator_minus | Subtract b to a. Binary operator. |

a * b | operator_multiply | Multiply a by b. |

a / b | operator_divide | Divide a by b. |

a % b | operator_modulo | Modulo of the division of a by b. |

a ** b | operator_power | Compute the power b of a. |

- a | operator_minus | Negate the value of a. Unary operator. |

a ++ | operator_plusPlus | Increment a by 1, reply the value before the incrementation. |

a – | operator_moinsMoins | Decrement a by 1, reply the value before the decrementation. |

Each operator has an associated function name. This function contains the concrete implementation of the operational semantic of the operator. This function can be redefined as explained in the operator overloading section.

The comparison operators on primitive types are listed below.

Operator | Function Name | Operator Semantic |
---|---|---|

a == b | operator_equals | Test if a and b are equal. |

a != b | operator_notEquals | Test if a and b are not equal. |

a === b | operator_tripleEquals | Test if a and b are equal. |

a !== b | operator_tripleNotEquals | Test if a and b are not equal. |

a < b | operator_lessThan | Test if a is lower than b (a, b cannot be boolean). |

a > b | operator_greaterThan | Test if a is greater than b (a, b cannot be boolean). |

a <= b | operator_lessEqualsThan | Test if a is lower than or equal to b (a, b cannot be boolean). |

a >= b | operator_greaterEqualsThan | Test if a is greater than or equal to b (a, b cannot be boolean). |

a <=> b | operator_spaceship | Replies a negative value if a < b, a positive value if a > b, otherwise 0. |

Each operator has an associated function name. This function contains the concrete implementation of the operational semantic of the operator. This function can be redefined as explained in the operator overloading section](#operator-overloading).

The comparison operators on objects are listed below.

Operator | Function Name | Operator Semantic |
---|---|---|

a == b | operator_equals | Test if a and b are equal. |

a != b | operator_notEquals | Test if a and b are not equal. |

a === b | operator_tripleEquals | Test if a and b are equal. |

a !== b | operator_tripleNotEquals | Test if a and b are not equal. |

a < b | operator_lessThan | Test if a is lower than b (a must be Comparable). |

a > b | operator_greaterThan | Test if a is greater than b (a must be Comparable). |

a <= b | operator_lessEqualsThan | Test if a is lower than or equal to b (a must be Comparable). |

a >= b | operator_greaterEqualsThan | Test if a is greater than or equal to b (a must be Comparable). |

a <=> b | operator_spaceship | Replies a negative value if a < b, a positive value if a > b, otherwise 0. |

Each operator has an associated function name. This function contains the concrete implementation of the operational semantic of the operator. This function can be redefined as explained in the operator overloading section](#operator-overloading).

The boolean operators are listed below. Each operator takes one or two boolean values as operands, and replies the boolean value resulting from the operational semantic of the operator.

Operator | Function Name | Operator Semantic |
---|---|---|

a || b | operator_or | If a then true else b. |

a && b | operator_and | If a then b else false. |

! a | operator_not | If a then false else true. |

Each operator has an associated function name. This function contains the concrete implementation of the operational semantic of the operator. This function can be redefined as explained in the operator overloading section.

The bit operators are listed below. The bit operators apply operations on the bits that represent a numeric value.

Operator | Function Name | Operator Semantic |
---|---|---|

a << b | operator_doubleLessThan | Shift the signed bit representation of a to the left by b units. |

a >> b | operator_doubleGreaterThan | Shift the signed bit representation of a to the left by b units. |

a <<< b | operator_tripleLessThan | Not supported. |

a >>> b | operator_tripleGreaterThan | Shift the unsigned bit representation of a to the left by b units |

Each operator has an associated function name. This function contains the concrete implementation of the operational semantic of the operator. This function can be redefined as explained in the operator overloading section.

Additional bitwise operators are available into the SARL library, but not associated to any operator:

Operator | Operator Semantic |
---|---|

a.bitwiseAnd(b) | Do a bit-per-bit AND operation. |

a.bitwiseOr(b) | Do a bit-per-bit OR operation. |

a.bitwiseXor(b) | Do a bit-per-bit XOR operation. |

a.bitwiseNot | Do a bit-per-bit NEGATION operation. |

The string operators are listed below. These operators are dedicated to strings of characters.

Operator | Function Name | Operator Semantic |
---|---|---|

a + b | operator_plus | Concatenate the string representations of a and b. |

This section presents a collection of operators that define ranges of values.

Operator | Function Name | Operator Semantic |
---|---|---|

a .. b | operator_upTo | Create a list of integer values from a (inclusive) to b (inclusive). `1..5` is the range from 1 to 5 with 1 <= x <= 5. `5..1` is the range from 5 to 1 with 5 >= x >= 1. The type of this expression is `IntegerRange` . |

a >.. b | operator_greaterThanDoubleDot | Create a list of integer values from a (exclusive) to b (inclusive). `5>..1` is the range from 4 to 1 with 5 > x >= 1. `1>..5` is the empty range since the constraint is wrong 1 > x >= 5. See Xtext for discussion on the operational semantics of this operator. The type of this expression is `ExclusiveRange` . |

a ..< b | operator_doubleDotLessThan | Create a list of integer values from a (inclusive) to b (exclusive). `1..<5` is the range from 1 to 5 with 1 <= x < 5. `5..<1` is the empty range since the constraint is wrong 5 <= x < 1. See Xtext for discussion on the operational semantics of this operator. The type of this expression is `ExclusiveRange` . |

The collection operators are listed below. These operators are dedicated to the collections (lists, sets, maps…) Most of the time, the first operand is the collection on which the operator must be applied.

Operator | Function Name | Operator Semantic |
---|---|---|

c += e | operator_add | Equivalent to: `c.add(e)` |

c -= e | operator_remove | Equivalent to: `c.remove(e)` |

c1 + c2 | operator_plus | Create a collection that is containing the elements of the collections `c1` and `c2` . |

m + p | operator_plus | Create a map of type `Map<A,B>` that is containing the elements of the map `m` and the new pair `p` of type `Pair<A,B>` . |

m - p | operator_moins | Create a map of type `Map<A,B>` that is containing the elements of the map `m` , except the pair `p` of type `Pair<A,B>` . |

a -> b | operator_mappedTo | Create an instance of `Pair<A,B>` where `A` and `B` are the types of a and b respectively. |

This section presents a collection of operators that are not related to the categories in the previous sections.

Operator | Function Name | Operator Semantic |
---|---|---|

a ?: b | operator_elvis | If a is not null then a else b. |

a => b | operator_doubleArrow | Used as a ‘with’- or ‘let’-operation. It allows you to bind an object to a local scope in order to do something on it. b must be a lambda expression. |

a <> b | operator_diamond | Not yet supported. |

For an example of the `=>`

operator, consider the class `Person`

with two attributes inside: `firstName`

and `lastName`

.
The creation of an instance of `Person`

could be done with:

```
new Person => [
firstName = 'Han';
lastName = 'Solo'
]
```

Note Note how the `;`

allows two expressions on one line.

In this example, the instance of Person is created and passed to the
lambda expression. Inside this expression, the new Person instance is accessible with the `it`

reserved pseudo-variable, which does not need to be typed out since it is the default object in
lambda expression. The lambda expression replies the value of `it`

.

The following table lists the precedence and associativity of SARL operators. Operators are listed top to bottom, in ascending precedence, i.e. from the lower priority to the higher priority.

Operators | Associativity | ||
---|---|---|---|

= | right to left | ||

left to right | |||

&& | left to right | ||

==, !=, ===, !== | left to right | ||

>=, <=, <, > | left to right | ||

instanceof | not associative | ||

<=>, <>, .., >.., ..<, ->, =>, ?:, », «, »>, «< | left to right | ||

+, - | left to right | ||

*, /, % | left to right | ||

as | left to right | ||

** | left to right | ||

!, - (unary), + (unrary) | right to left | ||

++, – | not associative | ||

feature, literal, closure, structure expressions | not associative |

When parsing an expression, an operator which is listed on some row of the table above with a precedence will be bound tighter (as if by parentheses) to its arguments than any operator that is listed on a row further above it with a lower precedence.

For example, the expressions `c << a == b`

and `-p++`

are parsed as `(c << a) == b`

and `-(p++)`

, and not as
`c << (a == b)`

or `(-p)++`

.

Operators that have the same precedence are bound to their arguments in the direction of their associativity.
For example, the expression `a = b = c`

is parsed as `a = (b = c)`

, and not as `(a = b) = c`

because of
right-to-left associativity of assignment, but `a + b - c`

is parsed `(a + b) - c`

and not `a + (b - c)`

because of left-to-right associativity of addition and subtraction.
Associativity specification is redundant for unary operators and is only shown for completeness:
unary postfix operators always associate left-to-right.
Note that the associativity is meaningful for member access operators, even though they are grouped with
unary postfix operators: `a.b++`

is parsed `(a.b)++`

and not `a.(b++)`

.
Operator precedence is unaffected by operator overloading.

Another example of operator precedence could be related to the extension method and the
expression `-125.abs`

.
This expression means that the function `abs`

is invoked with the value that is
mentioned before the dot character as first argument.
According to the precedence table above, this expression must be interpreted as `-abs(125`

.
Indeed, the feature call to the function `abs`

has a higher precedence than the minus
unary operator.

In SARL, it is easy to overload or re-define an existing operator.

You should define the operator mapping function (see the previous sections for a comprehensive list of them).

The following example, the addition operator [:plusop] for two `Pair`

objects is defined.
The function that is defining the operator must be named with the `operator_`

prefix, and have one parameter
for each operand associated with the operator. In the example, the addition of two pairs `1 -> 3`

and `4 -> 5`

.
gives the pair (a,d).

```
def operator_plus(
a : Pair<Integer,Integer>,
b : Pair<Integer,Integer>) : Pair<Integer,Integer> {
return new Pair(a.key, b.value)
}
def example {
var x = 1 -> 3
var y = 4 -> 5
// Old-fashion-style call to the overloaded operator
var z1 = operator_plus(x, y)
// Operator-style call to the overloaded operator
var z2 = x + y
// z1 == (1 -> 5)
println(z1.toString)
// z2 == (1 -> 5)
println(z2.toString)
}
```

In addition to the overloading of the operators that are described on this page, it is possible to overload the casting operator. See details.

This documentation is inspired by the documentations from the Xtext and Xtend projects.

- Specification: SARL General-purpose Agent-Oriented Programming Language (“Specification”)
- Version: 0.14
- Status: Draft Release
- Release: 2023-09-26

Copyright © 2014-2023 SARL.io, the Original Authors and Main Authors.

Documentation text and medias are licensed under the Creative Common CC-BY-SA-4.0; you may not use this file except in compliance with CC-BY-SA-4.0. You may obtain a copy of CC-BY-4.0.

Examples of SARL code are licensed under the Apache License, Version 2.0; you may not use this file except in compliance with the Apache License. You may obtain a copy of the Apache License.

You are free to reproduce the content of this page on copyleft websites such as Wikipedia.

Generated with the translator docs.generator 0.14.0-SNAPSHOT.