Cells

Memory in the interpreter is divided into 8-byte cells which can hold a single variable and its value, a value, or some program text. The type nb_cell_t describes the layout of each cell. Cells are combined to hold longer, more complex objects such as the tokenized program text, strings, and arrays.

Scratch memory

The interpreter stores variables and the expression stack in the scratch area at the beginning of memory: variables are allocated from the beginning of scratch memory in increasing address order, whilst expressions are placed onto the expression stack at the end of the scratch area in decreasing address order. When these two meet, an out of memory exception is raised (and the interpreter fully checks this).

Program memory

Immediately following the scratch area is the program text; it's a single object and never moves from its fixed place, although it does change in size. When the program size changes, because a user has edited the program, all variable values are lost as the program could overwrite objects held in free memory (the heap) as described later.

Heap

Following the program area is the heap, an area of free memory which is used to hold strings and arrays which are dynamically sized. These objects are created when required and allocated from free memory.

Dynamic objects are allocated from the heap using a first-fit algorithm. The free list head is kept in nb_first_free_index which is an index into the cell array. Each entry in the free list has type NB_TYPE_FREE and its length in cells is kept in the member length of free.

Both strings and arrays can be intermediate objects created during the evaluation of an expression, used, and then become unreferenced because they're not used again. For instance, consider the statement PRINT "A" & "B". In this case, the strings "A" and "B" are created, concatenated, printed, and are then orphaned with no references to them, and in doing so use six cells in the heap. As more and more intermediate objects are created and the heap consumed, it's inevitable that at some stage we'll hit the end of the heap, and when we do we trigger a garbage collection.