-
Notifications
You must be signed in to change notification settings - Fork 0
Syntax desugaring
A large amount Clay syntax, including almost every operator, is actually simplified into plain function calls (or sequences of function calls) by the Clay compiler. This page aims to document all of these transformations.
In the following tables, a, b, c represent arbitrary single-value subexpressions. ...a, ...b, ...c represent zero or more arbitrary subexpressions yielding zero or more values. foo, bar, bas represent literal identifiers. a;, b;, c; represent an arbitrary statement (including an arbitrary { ... } block). 0, 1, 2 represent literal integers. In the "equivalent" column, _x, _y, _z represent nonaccessible temporary variable names.
All referenced function names are looked up in the prelude module unless otherwise indicated. Note that if, for example, you create a new function named add in a different module, that new function will not affect the behavior of the + operator. When overloading operators, you must use the overload keyword to modify the existing operator functions in their original modules.
| Operator expression | Equivalent function expression | Notes |
+a |
plus(a)
|
|
-a |
minus(a)
|
|
&a |
__primitives__.addressOf(a) |
(1) |
*a |
(see Variant Dispatch) | (1) |
a[...b] |
index(a, ...b)
|
|
a(...b) |
call(a, ...b) |
(2) |
a.foo |
fieldRef(a, #foo)
|
|
a.0 |
staticIndex(a, static 0)
|
|
a^ |
dereference(a)
|
|
a * b |
multiply(a, b)
|
|
a / b |
divide(a, b)
|
|
a % b |
remainder(a, b)
|
|
a + b |
add(a, b)
|
|
a - b |
subtract(a, b)
|
|
a < b |
lesser?(a, b)
|
|
a <= b |
lesserEquals?(a, b)
|
|
a > b |
greater?(a, b)
|
|
a >= b |
greaterEquals?(a, b)
|
|
a == b |
equals?(a, b)
|
|
a != b |
notEquals?(a, b)
|
|
new a |
allocateShared(a)
|
|
if (a) b else c |
ifExpression(a, b, c) |
(3) |
[...a] |
arrayLiteral(...a)
|
|
() |
tupleLiteral()
|
|
(a, ...b) |
tupleLiteral(a, ...b)
|
Notes:
- Not overloadable.
- In the absence of a
calloverload for a static callable, the callable is invoked directly. -
ifExpressiononly affects the expression form ofif.ifstatements do not desugar into a function form.
Assignment in Clay is not an expression; however, the assignment operators still desugar into function calls:
| Assignment statement | Equivalent function statement | Notes |
a = b; |
assign(a, b); |
(1) |
a <-- b; |
(see Initialization) | |
a *= b; |
multiplyAssign(a, b);
|
|
a /= b; |
divideAssign(a, b);
|
|
a %= b; |
remainderAssign(a, b);
|
|
a += b; |
addAssign(a, b);
|
|
a -= b; |
subtractAssign(a, b);
|
Notes:
-
var a = b;andref a = b;for rvaluebboth behave like<--instead of callingassign. See Initialization.ref a = b;for lvaluebandalias a = b;bindatobrespectively as a greedy or lazy alias; there are no function equivalents to those operations.
| Control flow statement | Equivalent code |
for (a in b)
c;
|
{
ref _x = b;
var _y = iterator(_x);
while (hasNext?(_y)) {
ref a = next(_y);
c;
}
}
|
static for (a in ...b)
c;
|
{
alias a = <first element of b>;
c;
}
{
alias a = <second element of b>;
c;
}
/* ... */
|
The initializing assignment operator a <-- b; initializes the values on the left side as if they are uninitialized memory. The exact behavior of <-- depends on whether the expression b returns by value or by reference, or is a forwarded lvalue or rvalue:
| Conditions | Expression | Function call |
f is a function or operator that returns by value
|
a <-- f(...b);
|
f(...b)
|
b is a simple variable, or an expression that returns by ref
if a variable, b is not a forward argument, or is a forwarded lvalue
|
a <-- b;
|
copy(b)
|
b is a simple variable, or an expression that returns by ref
if a variable, b is a forwarded rvalue
|
a <-- b;
|
move(b)
|