Tuesday, September 22, 2009

Output ordering and Initializers

Output ordering

Today I got Close to emit functions in the same sequence they occur in the input file. That was easy.

What wasn't easy was automatically creating a namespace init function to handle initialized declarators.

If you compile code that looks like this:
int x = 10;
There's no function involved. Clearly, this is a global variable 'x', and its initial value is 10. But Parrot does not use the same model that *nix uses, of loading a file that contains a partial memory image. Since there's no data segment, any and all initialization have to be done by code.



That's where the namespace init functions come in. A namespace may contain variables and functions that depend on the variables. For the case of simple initialization - like the x = 10 case above - I'm willing to take care of that for you. If you want a more complicated initialization, where some data depends on the initialization of other data, well, you can write that code yourself. (Seriously - that's what the ':init' adverb is for.)

Executive decision

One decision I had to make was the order of declaration of the _nsp_init functions. Should they be declared (and, by the rules of Parrot, be executed) after other functions, or before them. My decision was that _nsp_init functions will be "declared" the first time the namespace appears. Any initializers in the namespace will (eventually - this doesn't work yet) get appended to the _nsp_init function.

This means that initializers cannot depend on user-specified :init functions having run. If you need that, then you will have to perform your own initialization.

Results

The result of this is all but invisible to you. But it means that this code:
namespace A::B {
    int x = 10;

    void my_init() :init {
        say(y);
        y = 20;
    }

    int y = 100;

    void main() :main {
        say(y);
    }
}
Will produce these subs, in this order:

:: _nsp_init // empty
:: A :: _nsp_init // empty
:: A :: B :: _nsp_init
x = 10
y = 100
:: A :: B :: my_init
:: A :: B :: main
Of course, the empty _nsp_init subs will be silently deleted by the compiler, so they never appear in the output. But if they had content, that was added later, say, they would be emitted in that order.

The output of running the code above would be:
100
20
 Because the _nsp_init function was emitted (and so, would run) before the my_init function.

1 comment:

  1. what a nice blog you have! i love the colors and the content, i wonder how you get such amazing ideas to write about. have a great day/night and thanks for this.

    ReplyDelete