HANDBOOK / GENTLE PRIMER /

# Handling Global Information

Gentle encourages a declarative style of programming. However, there are cases in which non declarative elements are appropriate.

One problem is parameter lists that tend to get too long if every bit of context information is passed explicitly.

Consider a programming language that features a loop-statement and exit-statement and specifies that an exit-statement can only occur inside a loop statement. To check this constraint, the predicate that processes statements would have to be equipped with a parameter indicating whether one is inside or outside a loop. This parameter must be passed for each statement, e.g. an if-statement, because a constituent of that statement - e.g. the then-part - could contain an exit-statement. On the other hand, the constraint checking involves only the loop-statement and the exit-statement.

Gentle provides global variables. They are often used to represent a concept that is global to the concept processed by a particular rule.

A global variable is introduced by a declaration of the form

- `'var'` Name : Type

For example,

       'var' CurLoopContext: LoopContext

declares a global variable with the name `CurLoopContext` of type `LoopContext` (for which we assume values `inside` and `outside`).

This variable cannot be used inside expressions and patterns. The only way to manipulate and inspect its value is the update statement and the query statement that can be used as a member in a rule body.

The update statement has the form

- Name `<-` Expression

which assigns the value of the Expression to the variable given by Name.

For example,

       CurLoopContext <- outside

sets the variable `CurLoopContext` to `outside`. The old value of the variable gets lost.

The query statement has the form

- Name `->` Pattern

It takes the value of the variable and matches it against the given pattern. This may succeed, defining the variable inside the pattern. It may also fail, in which case the query statements fails.

For example,

       CurLoopContext -> outside

succeeds only if the variable holds the value `outside`.

       CurLoopContext -> K

defines a new local variable of type `LoopContext` whose value is the current value of `CurLoopContext`.

It is an error to access a global variable in a query statement if the variable has not been defined by a preceding update statement. This error is checked when the query statement is executed. Hence, term data structures cannot be corrupted by uninitialized global variables.

We now show how the above loop exit constraint can be checked. Assume that a predicate `ProcessStatement` traverses the abstract syntax of statements (we leave out all details). This could be extended at two points:

       'rule' ProcessStatement(loop(Body)):
          CurLoopContext -> OldLoopContext
          CurLoopContext <- inside
          ProcessStatement(Body)
          CurLoopContext <- OldLoopContext

       'rule' ProcessStatement(exit):
          CurLoopContext -> K
          CheckContextForExit(K)