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. |
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.
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 . |
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 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. |
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.
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. |
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.
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.
Copyright © 2014-2024 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.