Global or local variable (in the SIC sense)?
Keywords: gildas-python

Next: Programmer documentation Up: Object status in SIC: Previous: Read-only or read-and-write? Contents Index

####
Global or local variable (in the SIC sense)?

`SicVar` and `SicStructure` instances have a `__siclevel__` attribute which is an integer set to the level of the corresponding variable in SIC (0 for global, 1 for first local level, and so on).

When SIC defines any variable, it automatically imports it in the Python `__main__` name space12. When this variable is SIC-local (when executing procedures for example), importing it in Python may overwrite a lower level instance which has the same name. To prevent this, the `Sic` object in Python `__main__` provides an array of 10 instances (one per level) which are used to temporarily store object which would have been erased. This array is named `localspaces` and objects are saved as attributes of its 10 elements. Consider these SIC procedures:

    SIC> type localtest1.sic
    define integer a
    let a 123
    pause
    @localtest2.sic
    SIC> type localtest2.sic
    define real a[3]
    pause

They will define local variables named ``A`' at different local levels. Let's define a global ``A`' variable and execute these procedures:

    SIC> define char a*8
    SIC> let a "qwertyui"
    SIC> @localtest1.sic
    SIC_2> define integer a
    SIC_2> let a 123
    SIC_2> pause
    SIC_3> python
    Entering interactive session. Type 'Sic()' to go back to SIC.
    >>> a
    123
    >>> a.__siclevel__
    1
    >>> Sic.localspaces[0].a
    'qwertyui'
    >>> Sic.localspaces[0].a.__siclevel__
    0

``a`' object currently in Python `__main__` is the level-1 SIC object. The SIC-global ``A`' variable has been saved as an attribute of the `Sic.localspaces[0]` element.
Let's go deeper:

    SIC_3> continue
    SIC_2> @localtest2.sic
    SIC_3> define real a[3]
    SIC_3> pause
    SIC_4> python
    Entering interactive session. Type 'Sic()' to go back to SIC.
    >>> a
    [ 0.  0.  0.]
    >>> a.__siclevel__
    2
    >>> vars(Sic.localspaces[0])
    {'a': 'qwertyui'}
    >>> vars(Sic.localspaces[1])
    {'a': 123}

Now we find the level-2 object in the Python `__main__`, and the 2 lower-level variables with the same name are saved in the `Sic.localspaces` array. At any stage, user can access its current-level variables in the Python `__main__`, but also any lower level ones through the `Sic.localspaces` array.
Let's end procedures:

    SIC_4> continue
    SIC> python
    Entering interactive session. Type 'Sic()' to go back to SIC.
    >>> a
    'qwertyui'
    >>> vars(Sic.localspaces[0])
    {}
    >>> vars(Sic.localspaces[1])
    {}

In an automatic cascading mechanism, the lower-level variables are moved back to the Python `__main__` when the current level one is deleted. The `Sic.localspaces` array is cleaned at the same time so their is no double reference for any object. Thus at the end of the procedures, the SIC-global variables are back in the Python `__main__`, and the `Sic.localspaces` array has no more attributes.

Remember that an object is saved in the `Sic.localspaces` array if and only if an upper level variable is defined with the same name. Thus, at any time, the Python `__main__` may contain objects from different levels. User does not have to care about the saving and unsaving mechanism: all is automatic and goes back as it was after procedure execution. He only has to know that he can access any lower level variable in the `Sic.localspaces` array.

Next: Programmer documentation Up: Object status in SIC: Previous: Read-only or read-and-write? Contents Index