Whistle syntax

This page shows the general syntax to write a valid Whistle script.

Line structure

Whistle programs are divided into lines. Each line is a sequence of characters terminated by a NEWLINE (\n) token or an end-of-file (EOF) token.

The \n and \EOF tokens are automatically added to the end of each line when the Whistle program runs.

Whitespace

Whitespace characters in Whistle are spaces (), carriage returns (\r), and tabs (\t).

Comments

A comment begins with two forward slashes (//). It can be placed on its own line, at the beginning of a line, or at the end of a line. The Whistle mapping engine ignores the text after the beginning of the comment.

There's no specific convention for multiline comments, but you can create multiline comments using multiple single line comments. Whistle doesn't support inline comments.

Delimiters

The following table describes the delimiters for Whistle scripts.

Delimiter Name Description Examples
( ) Parentheses Contains lists of parameters in function definitions and calls. def getTagName(input) {// Code that returns a tag name}
Defines precedence in expressions. // Without parentheses, returns 18.
10 - 2 + 2 * 5
// With parenthesis, returns -10.
10 - (2 + 2) * 5
, Comma Separates consecutive elements in arrays, and arguments in function definitions and function calls. // Separates elements in an array.
[1, 2, 123, 3, 4]
// Separates parameters in a function definition.
ReturnMappingError(dataType, dataVersion, error) {
// Return a formatted error message.
}


// Separates parameters when calling a function.
ReturnMappingError("TS", "R4", "Mapping error")
. Period Separates elements in a path. def ReturnStatus(input) { input.coding.code: "active"; }
Separates integers and decimals in Primitive number types. // Separates integers from decimals. Integers are on the
// left side of the period, and decimals are on the right side.
12.34
{ } Braces Declares a block. A block is an expression that creates a new output object and allows the statements within the block to write to that output object. // A block expression that constructs a container.
{ field1: 123 } // The function uses a block expression as the body.
def map(dataType, dataVersion) { field1: dataType, field2: dataVersion }
Interpolates strings // Interpolates the string, returns "10 + 10 = 20".
"10 + 10 = {10 + 10}"
[ ] Brackets Declares array types. // Declares an array and assigns it to variable myArray.
var myArray: ["a", 1, true]
Specifies an index in an array. // Selects the 0 element in myArray and returns "a".
myArray[0]
When used in the middle of a path, appends to an array. // Appends "b" to myArray.
var myArray[]: "b"
// Appends 2 to myArray.
var myArray[]: 2
// Appends false to myArray.
var myArray[]: false
When used as a suffix, iterates over an array. // Executes MyFunction and passes in each element of // myArray one at a time.
def MyFunction(a) { "{a}" }
// Returns ["a", "1", "true", "b", "2", "false"]
MyFunction(myArray[])
: Colon Assigns a source to a target. // Simple assignment.
var myValue: 10
var myVar: myValue
// Returns 10.
myVar
Assigns the return value of a function to a variable. // Returns an array of substrings from an input string // separated by a comma.
def SplitOnComma(text) {
split(text, ",") }


// A comma-separated string variable.
var myString: "comma,separated,string"
// Assigns the value of passing myString to MyFunction to the
// variable myVal.
var myVal: MyFunction(myString)
// Returns ["comma","separated","string"].
myVal
Assigns fields in a container. // Assignment in a container.
{ field1: 123 field2: [1, 2, 3] field3: [{ num: 321 }] }
:: Double colon References a Whistle package outside of the current package. otherpackage::OtherPackageFunction()
; Semicolon An optional statement terminator. Semicolons are optional and can be placed at the end of a line, statement, or logical grouping of data.

Each example pair with and without semicolons behaves identically.

Identifiers

An identifier is a sequence of alphanumeric characters used as the name of a function, variable, field, or any other Whistle data type.

The underscore (_) character can be used inside any identifier and as the first or last character in the identifier.

Basic identifiers

Basic identifiers are case-sensitive and must follow these requirements:

  • They must begin with a letter, underscore (_), or dollar sign ($). Subsequent characters can be alphanumeric characters, dollar signs, and underscores.
  • They must match the following regular expression: [$a-zA-Z_][$a-zA-Z_0-9]*.

Quoted identifiers

Quoted identifiers have the following properties:

  • They can contain any UTF-8 character if the UTF-8 character is surrounded by single quotes ('').
  • Single quotes and backslashes (\) inside strings must be escaped with a preceding backslash.
  • They must match the following regular expression: '\'' ('\\\'' | ~['])+ '\''.

Hybrid identifiers

Hybrid identifiers have the following properties:

  • They can contain and begin with alphanumeric characters, dollar signs ($), and underscores (_).
  • They can't begin with a number.
  • They can contain any non-alphanumeric character, including spaces, but not including newlines. Non-alphanumeric characters can be in any position if the characters are escaped with a preceding backslash (\).

Constants and literals

Numbers

The number constant consists of the following components, in order. A number doesn't need to use all the components.

  1. An optional minus sign (-) to indicate a negative number.
  2. One or more integers.
  3. An optional decimal point (.) followed by a decimal value.

Numbers must meet the following requirements:

  • They must match the following regular expression: -? [0-9]+ (. [0-9]+)?.
  • They must fit into a 64-bit floating point value.

If a number containing a decimal is converted into a string, the decimal is removed if the decimal is considered negligible. A decimal is negligible if it's less than the united in last place (ULP) of the integer value.

Strings

Whistle has two types of strings: basic strings and interpolated strings.

Basic strings

Basic strings have the following properties:

  • They can be zero or more UTF-8 characters enclosed in double quotes ("").
  • The double quote, backslash (\), and brace ({ and }) characters in a basic string must be escaped using a preceding backslash.

Interpolated strings

Interpolated strings have the following properties:

  • They have the same requirements and limitations as a basic string, but allow expressions in the string that are evaluated and inserted. The resulting string is a combination of the original string and the string representation of the evaluated expression.
  • They must be enclosed in brace {} characters.

Booleans

The boolean literal is expressed using the true and false constants.

Keywords

The following table shows the keywords in Whistle. A keyword is a word that's reserved by the language and has a special meaning. Keywords are case-sensitive.

Keywords marked with the * superscript can be used as identifiers. All other keywords are reserved and can't be used as identifiers.

and
append*
as
def
else
extend*
false
global
if
import
merge*
option
or
package
replace*
required
root
side
then
true
var