<- ^ .

Datatypes representation

5   Datatypes representation

ptroff is signed integer type of size of pointer.

        struct lambda_exp { void *fnc, *closure; }

5.1   Basic datatypes

int and bool is represented on stack and passed as ptroff. float is passed around as double*, on stack it's simply double. void -- (void*)whatever, if it needs to be passed, `whatever' cannot be relied upon to contain anything specific :). [*]->* -- struct lambda\_exp*.

5.2   Strings

        struct string {
                int len;
                char *data;
        }
len is length of string, in characters. data is string content, it does not have to be NUL terminated. Strings are passed as struct string*

5.3   Tuples

*[t1, ..., tn] is represented as pointer to array containing tuple content. All ti are treated, as if they where passed to function, i.e. sizeof(ti) == sizeof(void*).

        f(*['a,int,'b] x) {
                let (_, y, _) = x {use(y);}
        }
is translated to:

        f(void **x) {
                use((ptroff)x[1])
        }

5.4   Unions

        struct union_exp {
                ptroff sel;
                void *data;
        };
Values of sel are assigned sequentially from 0 [[maybe 1 would be better, use 0 for error marks of some kind, but I don't know what they could be needed for...]], in order they are given in union definition. Union values are passed between functions are struct union_exp*

5.5   Structures

They are treated much like C structures. They are always passed as pointers to structures. Similarly, if one structure contains another -- it contains pointer to it, not it directly, thus:

        struct foo {
                int x;
                string s;
        }

        struct bar {
                foo f;
                int z;
        }
is translated to:

        struct foo {
                int x;
                struct string *s;
        };

        struct bar {
                struct foo *f;
                int z;
        };

5.6   By value or by reference

Ints, floats and bools are passed by value. For floats it will require sth like this:

        float x,y,r;
        ...
        r = tan2(x,y*2);
to be translated to:

        {
                double _1, _2;
                _1 = x;
                _2 = y*2;
                r = *(double*)tan2(&_1,&_2);
        }
Value returned from tan2() has to be stored in GC_malloc'ed() area, otherwise it wouldn't typeof(tan2) would be not a subtype of *('a,'a)->'a.

Other datatypes (unions, structures, tuples and objects) are passed by reference.

There can be confusion with:

        f(*[int,int] a) 
        {
                let [x,y] = a in {
                        x = 10; 
                        y = 20
                }
        }

        g()
        {
                int x, y;

                x = 5;
                f([x,y]);
                // whatever here x is still 5, or 10?
        }
It is 5. However this more due to implementation, then to anything else, because it is inconsitent with:

        [x, y] = [10, 20];
after which x is 10 and y is 20. But this is general problem with treating variables as addresses on the left side of `='.

<- ^ .

Datatypes representation