exprv4:reference:operators



Operators

This page lists Expr operators and their direct behavior.

Operator precedence, associativity, grouping, and evaluation order are covered in the next chapter: Expression rules.


Arithmetic Operators

Arithmetic operators calculate numeric results. The + operator can also concatenate strings.

Operator Meaning Notes
+ add or concatenate numeric add for two numbers; string concatenation if a string is involved
- subtract numeric operands required
* multiply numeric operands required
/ divide numeric operands required; division by zero is an error
% modulo numeric operands required; modulo by zero is an error
** power numeric operands required

Examples:

2 + 3;          // 5
7 % 4;          // 3
2 ** 3;         // 8
'A' + 10;       // 'A10'

Notes:

  • + accepts number and string operands.
  • -, *, /, %, and ** require numeric operands.
  • Division by zero raises an error.
  • Modulo by zero raises an error.
  • Invalid power results raise an error.

Examples of invalid arithmetic:

10 / 0;         // error
10 % 0;         // error
none() + 1;     // error

Named Arithmetic Operators

When the host enables named-operator compatibility mode, these named forms are accepted:

Named operator Symbol operator
DIV /
MOD %

Named operators are case-insensitive when enabled.

10 DIV 2;       // 5
10 MOD 3;       // 1

Named operators are a compatibility feature. Do not assume they are enabled in all Expr contexts.


String Concatenation

The + operator concatenates when a string is involved.

'Tool ' + 3;        // 'Tool 3'
'X=' + 10 + ', Y=' + 20;

Concatenation is evaluated left to right according to normal operator rules.

1 + 2 + ' mm';      // '3 mm'
'Value: ' + 1 + 2;  // 'Value: 12'

Use parentheses when you want a calculation before concatenation:

'Value: ' + (1 + 2);    // 'Value: 3'

Other arithmetic operators do not parse numeric strings automatically.

'10' * 2;              // error
'10'.parse_num() * 2;  // 20

Comparison Operators

Comparison operators compare values and produce a boolean-style numeric result.

Operator Meaning Notes
== equal no cross-type equality coercion
!= not equal no cross-type equality coercion
> greater than numeric operands required
>= greater than or equal numeric operands required
< less than numeric operands required
<= less than or equal numeric operands required

Examples:

5 == 5;         // true
5 != 3;         // true
3 < 7;          // true

Equality does not convert between different value types.

1 == '1';       // false
1 != '1';       // true

Convert explicitly when needed:

'1'.parse_num() == 1;   // true

Relational operators require numeric operands.

5 > 3;          // true
'5' > 3;        // error

Named Comparison Operators

When named-operator compatibility mode is enabled, these forms are accepted:

Named operator Symbol operator
EQ ==
NE !=
GT >
GE >=
LT <
LE <=

Named operators are case-insensitive when enabled.


Logical Operators

Logical operators use truthiness rules. See Type system for exact truthiness behavior.

Operator Meaning Notes
! logical NOT unary operator
&& logical AND short-circuits
|| logical OR short-circuits
^^ logical XOR evaluates both operands

Examples:

!0;             // true
1 && 0;         // false
0 || 5;         // true
1 ^^ 1;         // false

&& short-circuits. If the left side is false, the right side is not evaluated.

0 && fail();    // fail() is not called

|| short-circuits. If the left side is true, the right side is not evaluated.

1 || fail();    // fail() is not called

^^ is logical XOR. It does not short-circuit because both sides are needed to determine the result.

Named Logical Operators

When named-operator compatibility mode is enabled, these forms are accepted:

Named operator Symbol operator
NOT !
AND &&
OR ||
XOR ^^

Named operators are case-insensitive when enabled.


Bitwise Operators

Bitwise operators operate on integer-style numeric values.

Operator Meaning Notes
~ bitwise NOT unary operator
& bitwise AND finite numeric operands required
| bitwise OR finite numeric operands required
^ bitwise XOR finite numeric operands required
<< left shift finite numeric operands required
>> right shift finite numeric operands required

Examples:

5 & 3;          // 1
5 | 2;          // 7
5 ^ 1;          // 4
1 << 3;         // 8
8 >> 2;         // 2

Notes:

  • Bitwise operators require finite numeric operands.
  • NaN is rejected.
  • Operands are treated as integer values for bitwise operations.
  • Shift count must be in the range 0 to 63.

Invalid examples:

nan() & 1;      // error
1 << 64;        // error
1 >> -1;        // error

Unary Operators

Unary operators apply to one operand.

Operator Meaning Operand rules
+x unary plus numeric operand required
-x unary minus numeric operand required
!x logical NOT uses truthiness
~x bitwise NOT finite numeric operand required

Examples:

+a;             // numeric identity
-a;             // numeric negation
!a;             // logical negation
~a;             // bitwise inversion

Unary plus is mostly useful for explicit numeric intent. Unary minus negates numeric values.

value = -10;
result = -value;    // 10

Assignment and Update Operators

Assignment and update operators modify variables.

Operator Meaning Notes
= assignment right-associative
+= add and assign uses normal + behavior
-= subtract and assign numeric update
*= multiply and assign numeric update
/= divide and assign numeric update; division by zero is an error
%= modulo and assign numeric update; modulo by zero is an error
**= power and assign numeric update
&= bitwise AND and assign finite numeric operands required
|= bitwise OR and assign finite numeric operands required
^= bitwise XOR and assign finite numeric operands required
<<= shift left and assign finite numeric operands required
>>= shift right and assign finite numeric operands required
++x pre-increment modifiable numeric variable required
x++ post-increment modifiable numeric variable required
--x pre-decrement modifiable numeric variable required
x-- post-decrement modifiable numeric variable required

Examples:

a = 5;
a += 2;         // 7
a *= 3;         // 21

Increment and decrement examples:

a = 5;
++a;            // 6
a++;            // returns old value, then increments
--a;
a--;

Notes:

  • Assignment is right-associative.
  • Assignment returns the assigned value.
  • Compound assignment returns the assigned value.
  • += uses normal + behavior, including string concatenation.
  • ++ and -- require a modifiable numeric variable.

Logical compound assignment operators are not part of Expr syntax:

a &&= b;        // not supported
a ||= b;        // not supported
a ^^= b;        // not supported

Assignment behavior is documented in detail in Variables and assignment.


Conditional Operator

The conditional operator chooses one of two expressions.

condition ? whenTrue : whenFalse

Example:

result = (a > 0) ? 'POS' : 'NEG';

The condition is evaluated using truthiness rules.

Only the selected branch is evaluated.

result = ready ? UseReadyValue() : UseFallbackValue();

If `ready` is true, only `UseReadyValue()` is called. If `ready` is false, only `UseFallbackValue()` is called.

The conditional operator is right-associative. See Expression rules for precedence and grouping details.


Operator Compatibility Options

Some operators also have named forms when the host enables named-operator compatibility mode.

Named forms include:

  • NOT, AND, OR, XOR
  • DIV, MOD
  • EQ, NE, GT, GE, LT, LE

Named operators are compatibility syntax. Prefer symbolic operators in normal Expr scripts unless the host context requires named forms.


Common Mistakes

Expecting Numeric Strings To Convert Automatically

'10' * 2;       // error

Use explicit parsing:

'10'.parse_num() * 2;

Expecting Cross-Type Equality Conversion

1 == '1';       // false

Convert explicitly if needed:

1 == '1'.parse_num();

Using Bitwise Operators With NaN

nan() & 1;      // error

Check first when input may be invalid:

if(value.is_num_notnan())
{
    result = value & 1;
};

Assuming Logical XOR Short-Circuits

^^ evaluates both operands. Do not use it to guard unsafe expressions.

valid ^^ dangerousCall();

Use && or || when you need short-circuit behavior.

Previous: Variables and assignment

Next: Expression rules

exprv4/reference/operators.txt · Last modified: by 127.0.0.1

Page Tools