Files
Rex-EMoolator-docs/docs/en/engine/arithmetic.md
Patryk Gensch df6cf2f3d3
Some checks failed
docs / deploy (push) Has been cancelled
docs / build (push) Has been cancelled
Added part of docs
2026-05-19 20:51:59 +02:00

181 lines
7.1 KiB
Markdown

# Arithmetic
The Piklib/BlooMoo engine performs computations exclusively inside **arithmetic expressions** enclosed in square brackets. Round parentheses are reserved for method-call argument lists and do not act as grouping inside expressions. This chapter describes the available operators, the typing rules, and the conversions between primitive types.
## Syntax
An arithmetic expression is written between square brackets. It may appear anywhere a value is expected — including as a method argument or as the value assigned to a field:
```
VARIABLE_NAME^SET([VAL1+VAL2]);
*["ANIMO_"+_I_]^PLAY();
```
Expressions can be nested using additional pairs of square brackets:
```
[[VAL1+VAL2]*VAL3]
```
## Typing rule
All binary operations in expressions follow a single rule:
> **The result's type and the right operand's type are both determined by the type of the left operand.**
The right operand is cast to the left operand's type before the operation is performed, and the result also has that type. Examples:
```
"Value" + 2.5 → "Value2.50000" # DOUBLE cast to STRING
2 + "3" → 5 # STRING cast to INTEGER
```
A consequence: operand order matters not only for non-commutative operators, but also for the type of the result.
## Type conversions
Within the typing rule, the right operand is cast according to the rules below.
### From `STRING`
| Target | Rule |
|---|---|
| [`INTEGER`](../reference/INTEGER.md) | An integer is extracted from the start of the text (similar to `parseInt`). If the text does not start with a number, the result is `0`. |
| [`DOUBLE`](../reference/DOUBLE.md) | Same as `INTEGER`, but the fractional part is preserved. The decimal separator is a dot. |
| [`BOOL`](../reference/BOOL.md) | Text matching a truthful value (`TRUE` or a non-zero number) yields `TRUE`; otherwise `FALSE`. |
```
"5" → 5
"Test" → 0
```
### From `INTEGER`
| Target | Rule |
|---|---|
| [`STRING`](../reference/STRING.md) | The decimal representation of the number. |
| [`DOUBLE`](../reference/DOUBLE.md) | The number with a zero fractional part (five zeros after the dot). |
| [`BOOL`](../reference/BOOL.md) | A non-zero value yields `TRUE`; `0` yields `FALSE`. |
```
5 → "5"
3 → 3.00000
-2 → TRUE
0 → FALSE
```
### From `DOUBLE`
| Target | Rule |
|---|---|
| [`STRING`](../reference/STRING.md) | Decimal representation with a dot and five fractional digits. For `0.0` the fractional part is omitted. |
| [`INTEGER`](../reference/INTEGER.md) | Rounded to the nearest integer; ties round up for positive values and down for negative values. |
| [`BOOL`](../reference/BOOL.md) | Indirect: first cast to `INTEGER` (with the rounding above), then to `BOOL`. Values in the open interval `(-0.5, 0.5)` give `FALSE`, all others `TRUE`. |
```
3.5 → "3.50000", 4, TRUE
0.0 → "0", 0, FALSE
0.45362 → "0.45362", 0, FALSE
1.00001 → "1.00001", 1, TRUE
-0.5 → "-0.50000", -1, TRUE
```
### From `BOOL`
| Target | Rule |
|---|---|
| [`STRING`](../reference/STRING.md) | `TRUE``"TRUE"`, `FALSE``"FALSE"`. |
| [`INTEGER`](../reference/INTEGER.md) | `TRUE``1`, `FALSE``0`. |
| [`DOUBLE`](../reference/DOUBLE.md) | `TRUE``1.00000`, `FALSE``0.00000`. |
## Arithmetic operators
Expressions support the following binary operators:
| Operator | Meaning |
|---|---|
| `+` | addition / concatenation |
| `-` | subtraction |
| `*` | multiplication |
| `@` | division |
| `%` | remainder |
### Addition (`+`)
| Left operand type | Behaviour |
|---|---|
| [`STRING`](../reference/STRING.md) | Concatenation of the right operand (after casting) onto the left. |
| [`INTEGER`](../reference/INTEGER.md) | Numeric sum. |
| [`DOUBLE`](../reference/DOUBLE.md) | Numeric sum. |
| [`BOOL`](../reference/BOOL.md) | Logical conjunction (`AND`). `TRUE + FALSE` yields `FALSE`. |
### Subtraction (`-`)
| Left operand type | Behaviour |
|---|---|
| [`STRING`](../reference/STRING.md) | No effect; the result is the left operand. |
| [`INTEGER`](../reference/INTEGER.md) | Numeric difference. |
| [`DOUBLE`](../reference/DOUBLE.md) | Numeric difference. |
| [`BOOL`](../reference/BOOL.md) | No effect; the result is the left operand. |
### Multiplication (`*`)
| Left operand type | Behaviour |
|---|---|
| [`STRING`](../reference/STRING.md) | No effect; the result is the left operand. |
| [`INTEGER`](../reference/INTEGER.md) | Numeric product. |
| [`DOUBLE`](../reference/DOUBLE.md) | Numeric product. |
| [`BOOL`](../reference/BOOL.md) | Logical disjunction (`OR`). `FALSE * TRUE` yields `TRUE`. |
### Division (`@`)
| Left operand type | Behaviour |
|---|---|
| [`STRING`](../reference/STRING.md) | No effect; the result is the left operand. |
| [`INTEGER`](../reference/INTEGER.md) | Integer quotient. |
| [`DOUBLE`](../reference/DOUBLE.md) | Floating-point quotient. |
| [`BOOL`](../reference/BOOL.md) | No effect; the result is the left operand. |
Dividing a numeric type by `0` crashes the engine.
### Remainder (`%`)
| Left operand type | Behaviour |
|---|---|
| [`STRING`](../reference/STRING.md) | No effect; the result is the left operand. |
| [`INTEGER`](../reference/INTEGER.md) | Remainder. |
| [`DOUBLE`](../reference/DOUBLE.md) | Remainder truncated to an integer and then cast back to `DOUBLE`. The fractional part is lost — for example, `1.5 % 2` yields `1.00000`, not `1.50000`. |
| [`BOOL`](../reference/BOOL.md) | No effect; the result is the left operand. |
Taking a remainder with `0` as the right operand crashes the engine.
## Comparison operators
Expressions support the standard comparisons: `==`, `!=`, `<`, `<=`, `>`, `>=`. The right operand is first cast to the left operand's type (per the [typing rule](#typing-rule)), and the comparison is then performed.
### Equality and inequality
`==` returns `TRUE` if both operands (after casting) are equal; `!=` returns the opposite. For [`STRING`](../reference/STRING.md) the comparison is character-by-character; for numeric types, it is value-based.
### Less / greater
| Left operand type | `<` returns `TRUE` if |
|---|---|
| [`STRING`](../reference/STRING.md) | The left operand is lexicographically smaller than the right (character-by-character in CP1250 encoding). |
| [`INTEGER`](../reference/INTEGER.md) | The left operand's value is smaller. |
| [`DOUBLE`](../reference/DOUBLE.md) | The left operand's value is smaller. |
| [`BOOL`](../reference/BOOL.md) | The left operand is `FALSE` and the right is `TRUE` (`FALSE < TRUE`). |
`>` returns `TRUE` in the symmetric cases. `<=` and `>=` are equivalent to `<` or `==`, and `>` or `==`, respectively.
## Logical operators
`&&` (conjunction) and `||` (disjunction) accept only [`BOOL`](../reference/BOOL.md) operands. Passing an operand of another type (even one that could be cast) crashes the engine.
| Operator | Result |
|---|---|
| `&&` | `TRUE` only if both operands are `TRUE`. |
| `||` | `TRUE` if at least one operand is `TRUE`. |
Inside the [compound `@IF` condition](scripts.md#compound-condition), `&&` and `||` behave the same way, but they are part of the condition string rather than operators of an arithmetic expression.