Expressions are evaluated from left to right.
CM operators have priorities that determine how their arguments are bound. Operators with higher priority take precedence over operators with lower priority. For instance, the value of the expression 1 + 2 * 3 is 7 and not 9, since the multiplication operator has higher priority than the addition operator.
Parentheses can be used to group expressions. For instance, the previous expression is equivalent to 1 + (2 * 3). If the other interpretation is desired (1 + 2) * 3 can be used instead.
Operators
Arithmetical operators
All arithmetical calculations on integral types wrap around when their bounds are exceeded.
Values of type float or double do not wrap around. Instead, inf
is produced for "positive infinity" and -inf
for "negative infinity".
Dividing integral values by zero throws an exception. Whereas dividing values of type float or double produces inf
.
Addition, subtraction, multiplication, and division
a = b + c; a = b - c; a = b*c; a = b/c;
Remainder (modulo) %
a = b%c;
Power **
a = b**c;
Absolute Value ||
a = |b|;
Increment ++ and decrement --
a = b++; a = ++b; a = b--; a = --b;
Arithmetic shift left << and right >>
int a = b << c; int a = b >> c;
Logical shift right >>>
int a = b >>> c;
bitand, bitor, bitxor, bit negation (~)
int a = b bitand c; int a = b bitor c; int a = b bitxor c; int a = ~b;
Boolean operators
Logical negation !
bool a = !b;
Comparisons
bool a = b == c; bool a = b != c; bool a = b < c; bool a = b > c; bool a = b <= c; bool a = b >= c;
and, or, xor
bool a = b and c; bool a = b or c; bool a = b xor c;
in
bool a = b in c;
The in operator performs membership tests of various kinds. The kind of membership test is determined by the type of the right hand side of the expression. The resulting value has type bool.
bool a = b !in c;
The !in operator is the negation of the in operator. Note that !in must be written exactly like that, without any blanks after the exclamation sign.
- Class membership
- When the right hand side is the name of a class, the expression tests class membership. The result is true if the left hand side is an instance of the class to the right or of any of its super classes, and false otherwise.
- Enumeration membership
- When the right hand side is the name of an enumeration type, the expression is true if the left hand side matches the integer value of an entry in the enumeration, and false otherwise.
- Collection membership
- When the right hand side is the name of a collection (seq/set/map/index), the expression is true if the left hand side is an element in the collection (key element for map and index).
- Object membership
- The behavior of the in operator when the right hand side is an object is to call the object's contains method, with the left hand side of the expression as only argument.
- String membership
- The in operator can be used for testing if a character is contained in a string.
Conditional operator ? :
The conditional operator ?: takes three operands: a condition and two expressions of the same type. The value of the first expression after the condition is returned if the condition is true, and the value of the other expression otherwise.
a > 0 ? b : c
This expression returns b if a is greater than zero, and c otherwise.
Default operator ??
The default operator ?? takes two operands: two expressions of the same type. The value of the first expression is returned if the expression is considered to be true, and the value of the other expression otherwise.
pln(s ?? "default");
If s is non-null it will be printed, otherwise "default" will be printed.
The default operator is syntactic sugar for the conditional operator. The following two statements are equivalent:
a ?? b
a ? a : b
String operators
String concatenation #
str a = 33 # " inch"; str b = 1 # 2 # 3;
String concatenation using the # operator is carried out using a new StrBuf for each expression. For performance, it's often better to use a StrBuf manually, preallocating it to a suitable size, and thereby avoiding a lot of redundant allocation of temporary memory.
Symbol #
symbol a = #alpha; symbol b = #"beta and gamma";
Resource lookup $
str a = $cancelButtonLabel;
Resolves to getRs("cancelButtonLabel", #:package).
Access operators
Dot .
The dot operator has multiple functions.
- Field access
bool a = b.myField;
- Static cast
int a = pi.int;
- Dynamic cast
MyClass a = object.MyClass;
- Enumeration access
fontWeight a = fontWeight.bold;
- Enumeration test
fontWeight a; bool b = a.bold;
Null safe field access .?
bool a = b.?myField;
Returns the field value if b is not null, and null otherwise (or a zero memory value if the field is not a class). Access is safe for subsequent dot-accesses in the same expression as well, so these two are actually identical:
int x = a.?b.?c.?d.?e; int y = a.?b.c.d.e;
Type conversion .:
MyClass a = object.:MyClass; callback = fn.:function(Control):int
Dynamic cast can always be done with the .: operator. The dot operator overloads to dynamic cast as well unless there are other prioritized overloads (package reference, enum value or enum test, field access).
Indexed access []
Object z = sequence[3];
Argument operators
All arguments in current method/function ..
public void f1(int a, int b) { super(..); } public void f2(int a, int b) { f1(..); }
All arguments other than the start and/or end -.. ..- -..-
public void f1(int a, int b) { } public void f2(int a, int b, bool x) { f1(..-); } public void f3(bool x, int a, int b) { f1(-..); } public void f4(bool x, int a, int b, bool y) { f1(-..-); }
All arguments from or after |.. ..|
public void f1(int a, int b) { } public void f2(bool x, bool y|, int a, int b) { f1(|..); } public void f3(int a, int b|, bool x, bool y) { f1(..|); }
All arguments and the rest of it rest: type[] name
public void f1(int a, int b, int c, int d) { f2(..); } public void f2(int a, rest: int[] otherInts) { //otherInts is null if no value is passed in. }
Special value operators
Range ..
range a = 0..9; for (i in 1..5) pln(i);
Tuple creation <>
<int, double> t = functionReturningTuple(); <int a, int b> = functionReturningTuple();
Operator Precedence Table
The following table lists all CM operators and their priorities. Some of the rows contain expressions which are not built-in operators but syntax extensions.
operator | name | priority | example |
---|---|---|---|
# | string append | 105 | a # b |
?: | conditional operator | a ? b : c | |
or | logical OR | 30 | a or b |
xor | logical XOR | 30 | a xor b |
and | logical AND | 40 | a and b |
== | equal | 42 | a == b |
!= | not equal | 42 | a <= b |
< | less than | 45 | a < b |
> | more than | 45 | a > b |
<= | less than or equal | 45 | a <= b |
>= | more than or equal | 45 | a >= b |
bitor | bitwise OR | 50 | a bitor c |
bitxor | bitwise XOR | 50 | a bitxor c |
bitand | bitwise AND | 70 | a bitand b |
in | member | 75 | a in b |
!in | not member | 75 | a !in b |
>> | arithmetic shift right | 100 | a >> b |
>>> | logical shift right | 100 | a >>> b |
<< | aritmethic shift left | 100 | a << b |
.. | range | 108 | a..b |
+ | addition | 110 | a + b |
- | subtraction | 110 | a - b |
* | multiplication | 120 | a * b |
/ | division | 120 | a / b |
% | remainder | 120 | a % b |
** | power | 130 | a ** b |
| | | absolute value | |a| | |
.: | type conversion | a.:type | |
~ | bitwise NOT | 510 | ~a |
! | logical NOT | 510 | !a |
++ | postincrement | 530 | a++ |
++ | preincrement | 530 | ++a |
-- | postdecrement | 530 | a-- |
-- | preincrement | 530 | --a |
- | arithmetic negation | 540 | -a |
[ ] | indexed access | 570 | a[b] |
Expressions
Basic CM Expressions
if as
if (z as TaggedComponent) return z.tag;
If statement with built in dynamic cast, z gets the more specific type within the if statement (positive) scope.
#:package
symbol pkg = #:package;
Resolves to the current package (e.g. the one stated at the top of your .cm source file).
#:package : caller eval
public void foo(symbol pkg=#:package : caller eval) { pln(pkg); }
Here the #:package is evaluated in the calling context.
#:src
SrcRef source = #:src;
Works as #:package above, but returnes the SrcRef at the call site (#:src is always caller eval).
Special value Expressions
Units
double a = 12 mm; double a = 12 cm; double a = 12 dm; double a = 12 m; double a = 12 inch; double a = 12 feet;
(deg) angle
angle a = 30deg;
(x, y, z) point
point p = (1, 2, 3.14); point2D p = (1, 3.14); pointI p = (1, 2);
(yaw, pitch, roll) orientation
orientation p = (30deg, 90deg, 280deg);
Comments
0 comments
Please sign in to leave a comment.