opCallOnce
| Syntax: | include <any_file_with_top-level_statements> |
| Description: |
Ensure any required top-level statements are invoked as required.
Suppose you have a file my_include.e (normal, hll) which contains, outside of any routine: puts(1,"Hello there\n") And a little test.exw program: include my_include.e --puts(1,"Hello there\n") You would (/should) expect the result to be the same when the statement in the include file is commented out and the one after the include statement is uncommented. Each file generates a hidden top-level subroutine, which the compiler invokes, but only when it needs to. Note the compiler does not emit pointless opCallOnce for include files with no top-level statements, however and of course there may be some top-level statements that you cannot immediately see, in the form of implicit [nested] opCallOnce statements. You might question whether the compiler should keep track of what it is doing and only invoke such hidden routines from one ideal place, however in practice it is all too easy to create a convoluted meshwork of mutually-including files, in other words and as a rebuttal question, if filea includes fileb and at the same time fileb includes filea, where precisely should the calls to the hidden top-level routines go? In some senses it gets even more confusing when some files are not included at the top-top-level but only at varying depths in a complex nested include hirarchy, and the precise order things will actually get executed in all starts to get a bit fuzzy. The compiler takes the easier route of planting opCallOnce that do nothing when already previously invoked, with the latter being achieved by setting a flag on the appropriate (hidden) symbol table entry. User code, and indeed even the builtin files themselves, should never explicitly invoke opCallOnce. |
| Defined in: | builtins\VM\pStack.e |