# GScript

Document v1.1 (Gavino, 6th December 2009)

## Introduction

GScript is a plugin that extends the Avisynth scripting language to provide additional control-flow constructs:

- multi-line conditionals (if-then-else blocks);
- 'while' loops;
- 'for' loops.

Rather than trying to simulate these constructs with functions, GScript effectively extends the language syntax, making it easy to use the new constructs in a natural way and in arbitrary combinations.

## The constructs in detail

### 'if' statement

    if ( condition ) {
      statements
    }
    else {
      statements
    }

where condition is any boolean expression.
The statements can be any Avisynth statements, including the GScript extensions themselves, and so the new constructs can be nested.
The else part may be omitted (equivalent to writing else {}).

GScript also provides the 'else if' construct (which may be repeated to create a chain of conditionals). Thus the full form of the if statement is:

    if ( condition ) {
      statements
    }
    else if ( condition ) {
      statements
    }
    else if (...) { ... }
    ...
    else {
      statements
    }

### 'while' loop

    while ( condition ) {
      statements
    }

The statements are repeated while the condition is true.

Example:

    while (Height() < h) {
      StackVertical(last, c)
    }

### 'for' loop

    for ( variable = init , limit , step ) {
      statements
    }

init, limit and step are integer expressions, with step non-zero. step is optional and defaults to 1.
First the variable is set to the value of init. The statements are repeated until the exit condition is met, ie variable exceeds limit (if step > 0), or is less then limit (if step < 0). After each iteration, variable is incremented by step. If the initial value satisfies the exit condition, the number of iterations will be zero.
The limit and step expressions are evaluated once only, before loop entry.
Assignments to the variable are permitted within the loop body (eg to force a premature loop exit).

Example:

    for (i=1, nBlurs) {
      Blur(0.5)
    }

## Using GScript

Once the plugin is loaded (either via LoadPlugin or by installing GScript.dll in your plugins folder), there are two ways to use the extended language features.

Firstly, a script (or part of a script) containing extensions can be passed as a text string to the GScript function (similar to the way functions like ScriptClip or MT are used). For example,

    GScript("""
    if (i > 10) {
      x = 1
      y = 2
      z = 3
    }
    else {
      x = 4
      y = 5
      z = 6
    }
    """)

The second way is to use the GImport function, which reads the entire contents of a file. This is similar to the standard Import, but supports the use of GScript extensions directly in the file. The advantage of this is that you don't have to put quotes around the script, or worry about possible problems if the embedded script itself contains both triple and single quotes. Thus, you can write entire scripts directly in the extended language and just pass to Avisynth a single GImport command to read it.

    GImport("MyGScript.avs")

For completeness, there is also a function GEval, analagous to the standard Eval, which evaluates an arbitrary string that is permitted to contain GScript extensions.

### Additional Notes

- As the 'GScript language' includes all standard Avisynth constructs too, you can even put your entire script inside a call to GScript if you want. There is no need to put each 'if' statement in a separate call, for example.
- A function declared inside the GScript environment can be called from outside, and vice versa. So you can add GScript constructs to a function without changing the calling code.
- Since all the new constructs are (compound) statements (like try..catch), and not expressions, they cannot appear on the right-hand side of an assignment.
- The loops are purely 'compile-time' constructs. There is no loop in the run-time filter graph, only in the construction of the graph (just as with a recursive function).
- Within GScript, comments are allowed before a '{'. This applies not only in the GScript constructs (if, etc), but also to standard uses of '{' in function declarations and try/catch. Arguably, it is a bug that Avisynth itself does not permit this (see this thread).

## Plugin Revision History

v1.1 (Gavino, 6th December 2009):
Bugs fixed:

- On some systems, a crash would occur when GScript attempted to report any kind of error (eg syntax error or Assert failure).
- In a while loop, the conditional test was evaluated before any implicit assignment to last on the final statement of the block, potentially causing the wrong value of last to be used in the condition.
- When incrementing a for loop variable at the end of the loop body, any user assignments to the variable in the body were ignored.
New extension:
- Within GScript, comments are allowed before a '{'.

v1.0 (Gavino, 18th June 2009): first release