# Gnosis Script Operators

Operators are used to perform operations on values or variables. Gnosis Script operators are organizes into groups and have an evaluation priority.

The following are the major operator groups in evaluation priority order from highest to lowest priority:

- Dot Operator
- Unary Operators
- Bitwise Operators
- Arithmetic Operators
- Comparison Operators
- Logical Operators
- Conditional Operators

## Dot Operator

The dot (**.**) operator is used to obtain an object property value, an array element, or dictionary key value. It can also be used has a simplified form of function calls.

The . operator has the highest priority over all other operators.

To get a dictionary values:

```
// Dictionary keys can be dynamicly assigned.
// Create a variable as the key name.
var key = "Dynamic Key";
// Create a dictionary.
var dict = {
1 : "value 1",
key : "value 2",
IdentifierKey = "value 3",
"String Key" : "value 4",
// Dictionary keys can be expluded if there is no value.
// Use the missing keyword to exclude the key from the dictionary.
"Optional Key" : Random(2) ? "value 5" : missing
};
"1 = {dict.(1)}\n
{key} = {dict.(key)}\n
IdentifierKey = {dict.IdentifierKey}\n
String Key = {dict.('String Key')}\n
Optional Key = {dict?.('Optional Key')}"
```

Returns:

```
1 = value 1
Dynamic Key = value 2
IdentifierKey = value 3
String Key = value 4
Optional Key = value 5
```

To get the an element of the array:

```
var a = ['A', 'B', 'C'];
a.(2)
```

Returns:

`B`

If the dot operator joins an identifier with a function call, the Identifier is treated as the first argument.

The following two expressions are equivalent:

```
Count(Items);
Items.Count()
```

### Non-strict ?. operator

The **?. **non-strict dot operator can be used when an object property, array element, dictionary key or the data item itself is not guaranteed to exist.

The non-strict dot operator will return null rather than an error.

```
var dict = { };
dict?.('Some Key')
```

Returns:

`null`

### Multi-key Dot operator

The **.[]** multi-key dot operator can be used to obtain several properties from the object or dictionary and get a new dictionary with requested key-value pairs only.

```
var dict = { FirstName='John', LastName='Smith', Age=30 };
dict.[FirstName, LastName]
```

Returns:

```
{
"FirstName": "John",
"LastName": "Smith"
}
```

The non-strict and multi-key operators can be combined ?.[] where null will be returned for the missing properties or keys.

```
var dict = { FirstName='John', LastName='Smith', Age=30 };
dict?.[LastName, City]
```

Results:

```
{
"LastName": "Smith",
"City": null
}
```

## Logical Operators

Logical operators are used to combine conditional statements.

The logical **and** and **or** operators determine the logic between values or variables.

The unary **not** operator determines the logical opposite of a value or variable.

Logical operators have lower priority than Comparison operators.

The **and** operator has higher priority over the **or** operator.

The **not **operator has the second highest priority below the Dot operator.

Operator | Description | Example |
---|---|---|

and | Returns True if both statements are True | x < 5 and x < 10 |

or | Returns True if one of the statements is True | x < 5 or x < 4 |

not | Reverse the result – returns False if the result is True | not(x < 5 and x < 10) |

### OR Operator

The **or** operator evaluates its parts from left to right and is lazy enough to stop assessing when a particular part conforms to *true*.

The result of the **or** operator equals the last evaluated part.

For example, if the *someValue* in the expression below conforms to true, the result is the value of *someValue*. Otherwise, the result returned is the ‘*someValue must be false*‘ text.

```
var someValue = 1;
someValue or "{someValue} must be false";
// result is 1
var someValue = 0;
someValue or '{someValue} must be false';
// result is '0 must be false'
var someValue = null;
someValue or '{someValue} must be false';
// result is 'must be false'
var someValue = missing;
someValue or '{someValue} must be false';
// result is 'must be false'
var someValue = false;
someValue or '{someValue} must be false';
// result is 'No must be false'
```

### AND Operator

The **and** operator evaluates its parts from left to right and is lazy enough to stop assessing when a particular part does not conform to *true*.

The result of the **and** operator equals the last part if all parts conform to true. Otherwise, the result of the** ****and** operator is *false*.

For example, the following expression results in **true** if the *someValue *conforms to *true*. Otherwise, the result is *false*.

```
var someValue = 0;
someValue and "{someValue} must be true"
// result is false
var someValue = 1;
someValue and "{someValue} must be true"
// result is '1 must be true'
var someValue = true;
someValue and '{someValue} must be true'
// result is 'Yes must be true'
```

### NOT Operator

The unary (**not**) operator reverses the result, returning *false *if the result is *true*.

```
var happy = true;
(not happy) ? "Cheer up!" : "Having a good day!";
```

## Comparison Operators

Comparison operators are used to compare two values or variables. Comparison operators have lower priority than Arithmetic operators. The Comparison operators are ordered below by priority from lower to higher.

Operator | Name | Example |
---|---|---|

== | Equal to | x == y |

!= | Not equal | x != y |

> | Greater than | x > y |

< | Less than | x < y |

>= | Greater than or equal to | x >= y |

<= | Less than or equal to | x <= y |

The **==** and **!=** operators have lower priority than other comparison operators. So, the result of the following expression is *true*.

`5 > 2 == 7 <= 9`

Note that Comparison operators require operands to be of the same or compatible types.

## Arithmetic Operators

Arithmetic operators are used with numeric values to perform common mathematical operations. The priority of arithmetic operators is standard.

Operator | Name | Example |
---|---|---|

+ | Addition | x + y |

– | Subtraction | x – y |

* | Multiplication | x * y |

/ | Division | x / y |

% | Modulus | x % y |

All the arithmetic operators can be used with number types only. The exception is the operator +, which can be utilized with other types, like strings, arrays, or dictionaries.

## Bitwise Operators

Bitwise operators are used to compare (binary) numbers. The following bit operators are supported by the highest to lowest priority. The (**<<)** and (**>>)** operators share the same priority.

Operator | Name | Description | Example |
---|---|---|---|

~ | NOT | Inverts all the bits | ~x |

& | AND | Sets each bit to 1 if both bits are 1 | x & y |

^ | XOR | Sets each bit to 1 if only one of two bits is 1 | x ^ y |

| | OR | Sets each bit to 1 if one of two bits is 1 | x | y |

<< | Shift right by pushing copies of the leftmost bit in from the left and let the rightmost bits fall off | Shift left by pushing zeros in from the right and let the leftmost bits fall off | x << 2 |

>> | Signed right shift | Shift right by pushing copies of the leftmost bit in from the left, and let the rightmost bits fall off | x >> 2 |

## Unary Operators

Unary plus **+ **and minus **– **operators operate on a single value or variable that will convert a string to a float if the string is a float value. Or convert the sign for the value or variable. Unary operators have a lower priority than the Dot operator.

### + operator

```
var x = "1.5";
var y = +x
// result is 1.5
var x = 1.5;
var y = +x
// result is 1.5
var x = "nan";
var y = +x
// Failed to convert String to Float.
```

### – operator

```
var x = "1.5";
var y = -x
// result is -1.5
var x = 1.5;
var y = -x
// result is -1.5
var x = "nan";
var y = -x
// Failed to convert String to Float.
```

## Conditional Operators

Conditional operators evaluate expressions if the condition expression conforms to *true*.

### Ternary Operator

The conditional ternary operator evaluates the ConditionExpression, and if it conforms to true, then the ExpressionForTrue is evaluated, and its result is used as a result of the ternary operator. Otherwise, *ExpressionForFalse *is assessed and is the result of the ternary operator.

`ContitionExpression ? ExpressionForTrue : ExpressionForFalse`

Since the ternary operator has the second lowest priority (after assignment), it can be easily chained with other ternary operators to handle multiple conditions.

```
someValue < 0
? 'Negative'
: someValue < 10
? 'Digit'
: 'Number'
```

See also the (if) operator and (switch) function for alternative conditional constructions.

### If Operator

The **if** Conditional operator evaluates an expression if the condition conforms to *true*.

`if (ContitionExpression) ExpressionIfTrue`

### Else Operator

The **else** Conditional operator is a lower-priority alternative to the Ternary operator.

```
if (ContitionExpression) ExpressionForTrue
else ExpressionForFalse
```

If the result of ConditionExpression conforms to *true*, then the ExpressionForTrue is evaluated, and its result is used as a result of the **if** operator. Otherwise, ExpressionForFalse is evaluated and becomes the result of the **if** operator (in short form, the result is *null *since there is no ExpressionForFalse).

The (**if**) operator can be chained with (**else**) operators to handle multiple conditions.

```
if (A<0) 'Negative'
else if (A<10) 'Digit'
else 'Number'
```

See also the Ternary operator and Switch function for alternative conditional constructions.

## Action Operators

Sometimes, it is convenient to terminate a sequence of statements with some result. For example, when checking for specific conditions and returning a result without continuing. Or to break from a loop based on some condition. The (**break**) and (**return**) operators are used for such cases.

### Break Operator

The **break** operator breaks the sequence with a null result. However, it is possible to provide a specific result using the **break with** operator.

The following example assigns ‘neg’ to variable B if variable A is less than zero; otherwise, ‘pos’ is assigned:

`B = (if (A < 0) break with 'neg', 'pos')`

### Return Operator

The **return** operator stops the function or the whole script (if outside of a function) with a null result. If a value or an expression follows the return operator, the latter is used as the function (or script) result.

```
foo(arg) => (
if (arg < 0) return 'neg';
'pos'
)
```

### Tail Operator

There is one more special form of the return operator (**tail**). It is helpful for recursive functions to imitate loops without consuming call stack to avoid stack overflow. The following example demonstrates *tail *recursion:

```
fact(i) => (
if (i == 0) return ToLong(1);
return tail (i * fact(i - 1));
);
fact(20);
```

## Parentheses

To change the order of operations, the parentheses are used:

`2 * (3 + 5)`

The parentheses also serve for grouping statements or substatements into one statement or substatement. The result of the group of statements equals the result of the last statement.

For example, groups of statements can be used in the Ternary operator to define complex logic for ExpressionForTrue or ExpressionForFalse.

`A > 0 ? (B = 'Positive', C = true) : (B = 'Negative', C = false)`