## Literals #

Literals are values that you write directly in the script, like `0.8`

or `120`

. There are

three kinds of literals:

- Numeric literal (with decimals):
`0.80`

,`100.0`

, etc.

They have type`Double`

. - Numeric literal (without decimals):
`120`

,`1234`

, etc.

They have type`Int`

. - Hexadecimal literal:
`0xA9F`

,`0x8D01`

, etc.

They have type`Word64`

. - Unit literal:
`()`

.

## Variables #

Variables are names that represent values, like `foo`

or `bar`

. They always start by a letter,

and are followed by zero or more letters or numbers. Examples of valid

variables are: `x`

, `y`

, `MyVariable`

, `ThisIsAVariable`

, `this2isavariable`

, `Year2018`

.

## Types #

Types are the kinds of values a script can work with. For instance,

there are numbers, times, or booleans. Types are used to clasify values

and to provide useful information when a script contains a mistake (like

adding a boolean to an integer, or passing the wrong parameter to a

function). A list of all types available in scripts follow:

`Int`

: Integer numbers. These are numbers without decimals.`Double`

: Double-precision floating numbers. These are numbers with decimals.`Bool`

: Truth values. This type has only two members:`true`

and`false`

.`Unit`

: A type with a single value:`()`

.`EpochTime`

: Points in time. For how to build values of this type, see the “Time functions” section.`Word16`

: Unsigned 16-bit integeres.`Word32`

: Unsigned 32-bit integeres.`Word64`

: Unsigned 64-bit integeres.`* -> *`

(function type): A value can also be a function. For instance, a function that takes a`Double`

and returns an`Int`

has type`Double -> Int`

.

## Functions #

Like we mentioned earlier (see the Types section), a variable can

contain a function. To apply an argument to a function, simply put in

parenthesis the argument right after the function variable. For example,

if we have a function called `f`

of type `Double -> Bool`

, and a variable `x`

of type `Double`

, the function `f`

can be applied to `x`

simply by typing `f(x)`

. The result will have type `Bool`

.

## The input function #

*Warning: this function is only available when using virtual parameters.*

There is a special predefined function called `input`

. It is used to get values from

the parameters associated to a virtual parameter. Its type is `Int -> EpochTime -> Double`

.

The first parameter is the parameter index. If you assigned two parameters to the virtual parameter, the first parameter has index 1, and the second parameter has index 2. The second argument of `input`

is the time to get the value from. For example, `input(1,now)`

will get the current value of the first parameter. If there is no value

at the given time, `()`

will be returned.

The alias `input1`

is also available, and it’s equivalent to `input(1,now)`

. This alias can be used when migrating scripts from masks to virtual parameters.

## The latestBefore function #

*Warning: this function is only available when using virtualparameters.*

This function gets the latest value from a parameter before a given

time. An example:

`x := latestBefore(now - days(3), 1);`

In this example, `x`

is set to the latest value of the parameter 1 before three days ago.

## The latestInput function #

*Warning: this function is only available when using virtualparameters.*

This function works similarly to `input`

, but only has the parameter

index argument. The time time will be automatically set to the time of

the latest value in the parameter.

Note: It is equivalent to `latestBefore(now)`

.

## Assignments #

To assign a value to a variable, the following syntax is used: `<variable> := <expression> ;`

Where `<variable> `

is any variable name, and `<expression>`

is any expression involving variables and literals. An example: `x := 2 + sqrt(3) ;`

After this statement, the value of `x`

will be the result of evaluating the expression `2 + sqrt(3)`

.

Please note the semicolon after the expression in the assignment syntax.

## Clearing a variable #

To clear the value of a variable, use the following syntax:

`<variable> ;`

After this statement, the variable will be left undefined.

## Conditionals #

Using conditionals you can choose to execute one of two options. The

syntax goes as follows:

```
IF <boolean expression>
THEN
<code 1>
ELSE
<code 2>
END_IF ;
```

The `ELSE`

part is

optional. This works too:

```
IF <boolean expression>
THEN
<code>
END_IF ;
```

This way, the code inside the conditional will only be executed if

the boolean expression evaluates to `true`

.

## Time loops #

Time loops are a handy tool to execute some code for a sequence of

time values. This is the syntax:

```
WITH <variable> FROM <time expression> TO <time expression> EVERY <time expression> DO
<code>
END_LOOP ;
```

This code will do as follows:

- Set the value of the variable to the value of the
`FROM`

time.

Therefore, the variable will hold a value of type`EpochTime`

. - Run the code.
- Increase the value of the variable by the value of the
`EVERY`

time. - Run the code.
- Repeat this procedure until the value of the variable reaches the

value of the`TO`

time.

An example:

```
acc := 0;
WITH t FROM now - days(5) TO now EVERY minutes(30) DO
x := input(1,t);
IF not(isUnit(x))
THEN acc := acc + x;
END_IF;
END_LOOP ;
```

This time loop will add all values from the input parameter 1 from

the last 5 days, every 30 minutes. The result will be stored in the`acc`

variable. Sometimes there is

no value at time `t`

, so we need

to use `isUnit`

to account for

this case.

## Predefined functions and

operators #

### Arithmetic

Addition (`+`

) and

substraction (`-`

) can be used

with `Int`

, `Double`

, and`EpochTime`

.

Multiplication and division only with `Int`

and `Double`

.

Division *always* gives a result of type `Double`

, to

account for potential inexact divisions. Exponentiation is done with`**`

. For

example, `2 ** 3 = 8`

.

### Boolean values

The boolean values are `True`

and `False`

.

Lower-cased variants (`true`

and`false`

) are also defined. The

function `not :: Bool -> Bool`

gives `True`

for `False`

, and`False`

for `True`

.

### Logical operators

`|| :: Bool -> Bool -> Bool`

:

Logical disjunction.`OR`

is also

accepted.`&& :: Bool -> Bool -> Bool`

:

Logical conjunction.`AND`

is also

accepted.`XOR :: Bool -> Bool -> Bool`

:

Exclusive disjunction.`isSet :: Int -> Int -> Bool`

:

Check if the bit indicated by the second argument is set. For any`n`

:`0 isSet n = False`

.

### Integer operators

`MOD :: Int -> Int -> Int`

:

Modulo operation. Example:`9 MOD 4 = 1`

.

### Truncation operator

The operator ` :: Double -> Int -> Double ``truncates a number to the given number of decimals.`

TRUNC`

is also accepted.

### Rounding functions

All rounding functions return integers. They accept both `Double`

and`Int`

arguments, but they leave `Int`

values

unmodified. The rounding functions are:

`floor`

: Round to the closest

smaller (or equal) integer.`ceiling`

: Round to the closest

bigger (or equal) integer.`round`

: Round to the closest

integer.`truncate`

: Round by removing

the decimal part.

### Comparison operators

All operators work with `Int`

and `Double`

, and

only values of the *same type* can be compared. The available

operators are:

`==`

: Equality. The use of equality with`Double`

is not

recommended.`<>`

: Inequality.`<`

: Less than.`<=`

: Less or equal to.`>`

: Greater than.`>=`

: Greater or equal to.

### Comparison functions

The functions `max`

and `min`

have two

arguments can be used with values of `Int`

, `Double`

, and`EpochTime`

. They return the smallest (or largest) of its arguments. For example:`max(-2,1) = 1`

,`min(-3,2) = -3`

.

### Sign functions

The functions `abs`

and `negate`

can be

applied to values of type `Int`

or `Double`

. The

function `abs`

returns

the absolute value of a number, and the function `negate`

calculates the opposite number.

### Time functions

`now :: EpochTime`

:

A constant value with the current time. Its value does*not*

change during the execution of the script.`seconds :: Int -> EpochTime`

:

A number of seconds.`minutes :: Int -> EpochTime`

:

Minutes.`hours :: Int -> EpochTime`

:

Hours.`weeks: Int -> EpochTime`

:

Weeks.`monthsAgo :: Int -> EpochTime`

:

The time a given number of months ago.`hour :: EpochTime -> EpochTime`

:

Returns time at the start of the hour.`day :: EpochTime -> EpochTime`

:

Returns time at the start of the day (midnight).`month :: EpochTime -> EpochTime`

:

Returns time at the start of the month.`year :: EpochTime -> EpochTime`

:

Returns time at the start of the year.

### Casting functions

`double :: Int -> Double`

:

Cast an`Int`

value to a`Double`

value.`boolToInt :: Bool -> Int`

:

Cast a`Bool`

value to

an`Int`

value.`False`

becomes`0`

, and`True`

becomes`1`

.`intToBool :: Int -> Bool`

:

Cast an`Int`

value to a`Bool`

value.`0`

becomes`False`

, and

anything else`True`

.`timeToInt :: EpochTime -> Int`

:

Cast an`EpochTime`

value to an`Int`

value. The

result is the number of seconds since January 1, 1970, 00:00, not

counting leap seconds. You can use`seconds`

to get the`EpochTime`

back.`doubleBits :: Double -> Word64`

:

Cast a`Double`

value

to an unsigned integer that has the same bits set.`fromDoubleBits :: Word64 -> Double`

.

The inverse function of`doubleBits`

.

### Floating point number

functions

`recip :: Double -> Double`

:

Calculate the inverse of a number. For example:`recip(2) = 0.5`

.`sqrt :: Double -> Double`

:

Calculate the square root of a number.`limit :: Double -> Double -> Double -> Double`

.

The expression`limit(l,u,x)`

will evaluate to:`l`

if`x <= l`

.`u`

if`x >= u`

.`x`

otherwise.

### Unsigned integer functions

These functions work with `Word16`

, `Word32`

and`Word64`

types. We would refer to them as `WordN`

in the following functions.

`testBit :: WordN -> Int -> Bool`

:

Test if the nth bit is 1.`setBit :: WordN -> Int -> WordN`

:

Set the nth bit to 1.`clearBit :: WordN -> Int -> WordN`

:

Set the nth bit to 0.`complementBit :: WordN -> Int -> WordN`

:

Set the nth bit to 0 if it’s 1, or to 1 otherwise.`complement :: WordN -> WordN`

:

Complement every bit. Example:`complement(0xF0) = 0x0F`

.`shift :: WordN -> Int -> WordN`

:

Shift the given number of bits. The number can be negative for a

negative shift. Examples:`shift(0x0F0,4) = 0xF00`

,`shift(0x0F0,-4) = 0x00F`

,`shift(0x0F0,-8) = 0x0`

.`fromWord :: WordN -> Int`

:

Transform to signed integer. Overflow possible if argument is outside of

the signed integer type range.

### Unsigned integer operators

`.&.`

:

bit-wise and.`.|.`

:

bit-wise or.`XOR`

:

bit-wise xor.

### Transforming

between different unsigned integer types

Three functions are available: `toWord16`

, `toWord32`

and `toWord64`

. They all work for all

unsigned integer types. If the target type is smaller than the argument

type, any excess bits will be truncated. The function `toWord64`

can also be used to produce a`Word64`

from an `Int`

, which

will have the same bit representation as the original `Int`

but might

have a different value.

### Random numbers

`random :: () -> Double`

:

Get a random number in the`[0,1)`

interval. Example where`x`

is

assigned a random number between 0 and 10:`x := 10 * random() ;`

.

The`()`

argument is needed to

make possible that each time`random`

is called a new random value

can be generated.

### Unit check

The function `isUnit :: * -> Bool`

accepts arguments of *any* type, and returns `True`

when the

argument is `()`

.

### Trigonometrics

`pi :: Double`

.

The Pi constant.`sin :: Double -> Double`

.

Sine.`cos :: Double -> Double`

.

Cosine.`tan :: Double -> Double`

.

Tangent.

### Unit Check

The function `isUnit :: * -> Bool`

accepts arguments of *any* type, and returns `True`

when the

argument is `()`

.

### Trigonometrics

`pi :: Double`

. The Pi constant.`sin :: Double -> Double`

. Sine.`cos :: Double -> Double`

. Cosine.`tan :: Double -> Double`

. Tangent.