A-Shell/BASIC language enhancement (compiler edit 624):
++PRAGMA PRIVATE_BEGIN
<map and dimx statements>
++PRAGMA PRIVATE_END
This new set of pragmas may be used within ++include files to ensure that the module's private variables (MAP and DIMX) are initialized once and only once before they are used, regardless of the position of the ++include in the main program. Previously, without the benefit of the new pragmas, it was left to the programmer to make sure that any such MAP statements containing initializers, and any DIMX statements, got executed, just once, before being used. Typically that required that the ++include be at the top of the main program, so that execution fell through the MAP and DIMX statements before the main program started executing, or it required a static control variable and some conditional logic within the ++include module to keep track of whether the initializations had occurred.
With the new pragmas, the compiler takes care of the problem, making sure that the enclosed MAP and DIMX statements are initialized before any of the functions or procedures within the module are executed.
Secondarily, as a syntactic convenience, the keyword PRIVATE will be automatically added to any MAP or DIMX statement enclosed by the pragmas if not already explicitly specified. Thus, if you really do want to specify global variables within such a ++include module, you must keep then outside the set of pragmas lest they be turned into module private variables.
Notes
• | Each ++include module can have only a single pair of these pragmas |
• | The feature is entirely implemented in the compiler, so there is no requirement for a corresponding update of the runtime system. |
Example
! (main program)
...
if Fn'GetTableItem$(X) = "" then
call SetTableItem(X, "Behold!")
endif
...
++include table.bsi
- - - - - - - - -
! (table.bsi)
++pragma private_begin
map1 table'max,f,6,5000
dimx table(table'max),s,100
++pragma private_end
...
Function Fn'GetTableItem$(idx as f) as s100
if (idx <= table'max) then Fn'Table$ = table(idx)
EndFunction
Procedure SetTableItem(idx as f, item$ as s100)
if (idx <= table'max) then table(idx) = item$
EndProcedure
In the above example, the module table.bsi contains a private DIMX array table() which is shared by the function and procedure in the module. Because the module is included at the bottom of the main program, without the ++pragma private_begin, the array would still be unitialized at the point it was referenced in the Fn'GetTableItem$() function, leading to an error. To correct for that, the ++include statement would have to be moved to the top of the main program, but that is an undesirable dependency which the programmer creating the table.bsi would rather not have to depend on. And it is otherwise not easy to code around the problem. But with the ++pragma private_begin, the problem disappears.