Values passed as polymorphic parameters has to be all of the same size. Otherwise we wouldn't be able to generate efficient code. Specially for this purpose `int' Gont type is chosen with the same as size as machine pointer. (This is not the choice of some C compilers on some 64 bit architectures, for example on alpha-*-linux with GCC sizeof(int) = 4, sizeof(long) = sizeof(void*) = 8).
They are few basic types of passing arguments in Gont.
[[Functional values are currently always passed as pointers to the heap. I guess some semantic analysis will be done to pass it as pointers to stack when it is safe. Similarly for function closures.]]
Functional values cannot be passed simply as pointers to functions, since they might need closure in some (most?) cases. Here is layout of data structure describing functional value:
void *fnc;
void *closure;
closure has to be passed as the first argument to fnc. Closure must not point into the stack.
Pseudocode example:
foo()
{
int x;
int y;
g()
{
int p;
use(p);
use(x);
}
use(x);
use(y);
use(g);
}
is translated to:
struct foo_closure {
int x;
}
foo_lambda1(foo_closure *ptr)
{
int p;
use(p);
use(ptr->x);
}
foo()
{
int y;
foo_closure *cl = make_closure(...);
void *g = make_lambda(foo_lambda1, cl);
use(cl->x);
use(y);
use(g);
}
(Examples are given using pseudo-Gont as input, and pseudo-C as output, just to not confuse reader with Ksi syntax).
One might note that it might be impossible to pass regular function this way. We need auxiliary function to be generated.