Tabitha Programming Guide

Declarations

A variable declaration is a statement which describes a varaible to be used in some scope. In Tabitha, there are three main kinds of variable declaration:

The main difference between each type of declaration is scope. Stacked variables should only be used within the current block. Heaped variable can be use by any part of the code which has the address of the variable. Context varaibles should only be used within functions which have captured the relevant contexts.

Stacked Declaration

The most straight-forward kind of varaible declaration in Tabitha is the stacked variable declaration.

function foo {
    Int x                   # this is a stacked variable declaration 
    stacked Float y = 3.14  # this is also a stacked variable declaration
}

To declare a stacked variable, we need to be inside a function. By default, all variables declared inside a function are stacked, but we can choose to be explicit and use he stacked keyword. It is optional whether or not we specify an initial value for the variable. The stack is a piece of memory gien to your program by the operating system,
and is essential a linear space in memory. The stack can be pushed to or popped from. The stack is reset upon return from a function, hence the restriction that stacked variables shuld really only be used within the block in which they are declared (or any children of that block).

Heaped Declaration

Heaped declarations also take place within functions, but there is a difference in the syntax.

function foo {
    heaped Int x    = 10    # this is a heaped variable declaration
    heaped Float y  = 3.14  # this is also a heaped varialbe declaration
}

A heaped variable can be used by name within the block in which it is declared. They can also be used however by any part of the code which has the variable’s address. Here is an example:

attach external std

function foo {
    Addr[Int] x = bar()
    std::printIntLn(@x)
}

function bar -> Addr[Int] {
    heaped Int x = 10
    return x? 
}

The result of compiling and running this program would be that 10 is printed to the console. This example is not guaranteed to work if we had made x a stacked varaible in bar. The reason for this, is that heaped variables are allocated on the memory heap. This is a large chuck of memory provided to t he program by the operating system. It is less organised than the stack, and is not affected by a function returning. Data allocated on the heap persists until it is explicitly deallocated. Therefore, so long as we have the memory address, we can access and modify the data.

Memory can be deallocated (or freed) by an unheap statement. Since many complex datatypes can find themselves heaped, the unheap statement takes an optinal argument describing the type of data which is to be deallocated. If this argument is not provided, the type is inferred.

heaped Int x
unheap x? # implicitly unheaps the data at x? as an Int

heaped Vec[Int, 10] x
unheap x? # implicitly unheaps the data at x? as a Vec[Int, 10]

heaped Vec[Vec[Int, 10], 10] x
unheap x? as Vec[Addr[Int], 10] # deallocates the top-level vector
                                # but not any of its elements

So we see that unheap statements take an address to some heaped data, and the type of that heaped data. We have to use addresses here, for the name of variable may no longer be in scope.

Context/Dump Declaration

Although the usage of these variable differ from each other, the mechanics of declaring context variables and dump variables are very similar. Declaraing a variable inside a context or a dump is very smple.

context Data {
    Int x
    Float y
    std::String msg = "hello"
    Vec[Int, 10] scores
}

dump Const {
    Float pi = 3.14 
}

Context and dump variables primiarily reside in the data section of the program’s binary. That means that the variables are effectively a part of the program itself, and are not just created by the code during runtime. The exception to this, is what happens with vectors and tables. The elements of these are actually stored on the heap, but the handls are in the data section.