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 typeDouble
. - Numeric literal (without decimals):
120
,1234
, etc.
They have typeInt
. - Hexadecimal literal:
0xA9F
,0x8D01
, etc.
They have typeWord64
. - 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
andfalse
.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 aDouble
and returns anInt
has typeDouble -> 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 virtual
parameters.
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 virtual
parameters.
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 typeEpochTime
. - 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 theTO
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 theacc
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
, andEpochTime
.
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
andfalse
) are also defined. The
function not :: Bool -> Bool
gives True
for False
, andFalse
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 anyn
: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
andInt
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 withDouble
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
, andEpochTime
. 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 anInt
value to aDouble
value.boolToInt :: Bool -> Int
:
Cast aBool
value to
anInt
value.False
becomes0
, andTrue
becomes1
.intToBool :: Int -> Bool
:
Cast anInt
value to aBool
value.0
becomesFalse
, and
anything elseTrue
.timeToInt :: EpochTime -> Int
:
Cast anEpochTime
value to anInt
value. The
result is the number of seconds since January 1, 1970, 00:00, not
counting leap seconds. You can useseconds
to get theEpochTime
back.doubleBits :: Double -> Word64
:
Cast aDouble
value
to an unsigned integer that has the same bits set.fromDoubleBits :: Word64 -> Double
.
The inverse function ofdoubleBits
.
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 expressionlimit(l,u,x)
will evaluate to:l
ifx <= l
.u
ifx >= u
.x
otherwise.
Unsigned integer functions
These functions work with Word16
, Word32
andWord64
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 aWord64
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 wherex
is
assigned a random number between 0 and 10:x := 10 * random() ;
.
The()
argument is needed to
make possible that each timerandom
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.