An execution model is applied to the constructs defined by the Data Explorer scripting language. This model consists of the environment structure that is maintained during function calls, the behavior associated with macro expansions, the scope rules used for locating the value associated with a variable, and the semantics associated with assignment statements and function calls.
All global assignment statements and initial function invocations occur in the top-level environment. This environment is special in that all assignment statements and function invocations initiated in this environment are always executed.
When either a macro or a module function is executed, a new dynamically scoped environment specific to that function call is created. Variables that correspond to the function's input and output formal parameters are created in this new environment. The variables corresponding to the output formal parameters are initialized to NULL. Those variables corresponding to the input formal parameters are initialized in the manner described in the preceding section. If an input and an output formal parameter both have the same name, then they share a single parameter and are initialized to the value passed as input when the function is called.
When the function being called is a macro, the macro is effectively expanded in-line after first constructing the necessary environment for its input and output parameters. This guarantees that the partial orderings defined by macros are maintained.
The Data Explorer allows you to use variables on both the left and right sides of a function assignment; that is, as both left-side and right-side.
All assignments in a macro's environment affect variables that are local to the macro. These variables, if they do not already exist, are created in the macro's environment when they are first used on the left-hand side of an assignment expression. Thus, a variable outside of a macro cannot be modified with that macro.
The only way to make such a change is to propagate a new value out of the macro using its output formal parameters, and to use this returned value in an assignment statement in the enclosing environment.
Given these semantics, it is possible for a local version of a variable to come into existence and obscure a more global version of a variable, midway through a macro's execution.
The values of variables used in a macro in expressions and as function arguments are found according to standard dynamic scoping rules. If the variable exists in the macro's local environment, then its value is used. Otherwise, the enclosing environments, all the way to the top-level environment, are searched to locate the variable. The value used is the value associated with the first instance of the variable. If the variable is not found in any environment, then the value NULL is used.
The following is a sample script that illustrates how variables are treated in macros:
// This is a complete sample script macro add(a, b) -> (sum) { c = a + b; // c is created and given the value a+b c = a + x; // x is found in the top level, and used in this expression c = a + z; // z does not exist anywhere; NULL is used sum = a + b; // sum is created local to the macro, separate from the // version of sum in the top level } x = 7; sum = 10; total = add(4, 4); // total = 8, sum stays at 10
As stated earlier, all assignment statements and function calls initiated at the top-level environment are executed. In a macro, the process is slightly different. When a macro is expanded, its statements are first analyzed to determine whether they need to be executed. The rule of thumb for determining if a statement will be executed is that it must contribute, either directly or indirectly, to:
There are two kinds of "side effect" modules:
The macro sum3 in the following example computes both the sum of its first two arguments and the sum of all three of its arguments. When the top-level assignment statement on line 7 is executed, the statements in lines 3 and 4 are both executed, resulting in the values 11 and 111 being assigned to the top-level variables x and y respectively. When the top-level assignment statement on line 8 is executed, only the statement on line 3 is executed. Since the value in the output variable e is not assigned to anything in the calling environment, the statement on line 4 need not be executed.
macro sum3 (a, b, c) -> (d, e) // 1 { // 2 d = a + b; // 3 e = d + c; // 4 } // 5 // 6 x, y = sum3 (1, 10, 100); // 7 x = sum3 (1, 10, 100); // 8
[ OpenDX Home at IBM | OpenDX.org ]