Language Constructs

Comments

You can have both line comments and multiline comments. Single line comments start with a double slash and end at the line end:

// This is a line comment

Block comments start with /* and end with */ and they can be nested.

/*
    This is a
    multiline comment and
    /* you can nest multiline comments */
    as well
*/

Constants

GP Script supports integer, floating point, boolean and string constants (more on strings below). For convenience, MIDI note names can be used in place of integers. E.g, C3 is the same as 60, D#4 (or Eb4) is the same as 75.

Declarations

You can declare global variables and local variables. The general syntax for a declaration is:

var identifier : type

If you want to declare multiple variables of the same type, just separate them with a comma:

var i, j, k : integer

If you are declaring multiple variables one after the other, you do not need to repeat the var keyword (although you can)

var i : integer
    s : string
    n : NoteMessage

Global variable are defined outside of any callbacks or user-defined functions and are visible only from the point at which you declare them. Certain types such as Plugins, Widgets and function generators (ADSR, Ramp, etc.,) can only be declared at global scope.

Todo

which ones exactly?

The type system

All variables must be declared with a type.

Primitive types

Primitive types include Integer, Double and Boolean. With a couple of exceptions, operators for primitive types are part of the language syntax itself. For example, arithmetic operators (+, - , *, /, %) and comparators (<, <=, ==, !=, >, >=) can be used on both Integer and Double.

Opaque types

Opaque types are types whose behavior is controlled completely by system functions and you have no direct access to them. Variables that refer to “physical” widgets and plugin blocks instances of opaque types. Some opaque data types do not have any “physical” existence. These include function generators, the NoteTracker and the ChordRecognizer types. Over time, as new functionality is added to Gig Performer, more opaque data types are likely to be added.

Hybrid types

There are a couple of types that are treated specially, with some built-in operations even though they are otherwise opaque.

Strings

Language designers struggle with the best way to handle strings. Some leave all string processing up to their libraries (but still have language support to define string constants), others make strings be a special type with language support. GP Script adopts the latter approach. While there are as yet no string processing system functions (and it´s unclear what functions might actually be needed within the context of Gig Performer automation), the + operator is overloaded so that strings can be concatenated together. More importantly, if you start an expression with a string type, then the RHS of the + operator can be of type Integer or Double and the value will be automatically converted to a string type. This makes it easy to write such things as

Print("The value is " + i) // Display the value of i in the script log window

and is mainly intended for debugging purposes although it can be convenient to use this mechanism to set the caption of a label or widget, e.g.,

SetWidgetCaption(w, "Value: " + v)

Arrays

It is possible to have arrays of types (although currently you cannot have an array of arrays). Arrays currently have a maximum length of 128 (no prizes for guessing why that value). Array indexing is zero-based.

var mySmallArray : Integer[32]

This creates an array that can contain 32 values. Attempts to reference the array outside the defined range will be trapped by the runtime system and the script terminated. While this adds a little cost, we feel that array range errors are sufficiently common that it´s worth the cost. In the future, we may add an option to disable range checking.

You can pass arrays as dynamic parameters to functions and the system function Size will return the current size of the array parameter.

Function IntSum(someArray : Integer array) returns Integer
    var s : Integer  // Track the sum
    index : Integer

    For i = 0; i < Size(someArray); i = i + 1 do
        s = s + someArray[i]
    End

    result = s  // Return the result
End

Dynamic arrays

Rather than defining a constant size, you can add the keyword array after any primitive type to create a dynamic array. For example, the following declaration is allowed:

Var
    Fader1, Fader2, Fader3, Fader4 : Widget
    Faders : Widget array

Initialization
    Faders = [Fader1, Fader2, Fader3, Fader4] // Array initialization
End

Then you can use array indices to reference individual widgets. The Size function works as expected and will return the current size of the array which of course is 4 in the above example.

Operators

Boolean operators

GP Script includes the usual Boolean operators but has some interesting additions to make scripting a little easier for users.

Todo

which?

in

The in operator allows the left hand side, normally an integer (Integer) or a floating point number (Double) to be tested against an integer or floating point respectively range. So you can write:

If n in [C3..C4] Then

The variable n would normally be an integer type. However, this will also work if n is a NoteMessage or a ControlChangeMessage and in these cases the note number or controller number will be used.