Safe FORTH with the FORTRAN memory model?

Kragen Javier Sitaker, 02021-04-21 (updated 02021-06-12) (2 minutes)

What if we use the Fortran memory model in Forth? With bounds checking? No more free access to memory. Like, a segmented kind of thing.

Create a scalar variable x with value 3:

3 value x

Set it to 4:

4 to x

Create an array a containing the values 0, 1, 4, 9, 16:

create a 0 , 1 , 4 , 9 , 16 ,

Load 9 from its position 3, with bounds checking:

a 3 @

Store -4 in its position 2, overwriting 4:

-4 a 2 !

Define a word “cons” that allocates two cells and stores values on the stack in them:

: cons create , , ;

Use it:

3 4 cons mycon

Define a word “cdr” that loads the second field, and use it:

: cdr 1 @ ;
mycon cdr

Define a different word “cons” that defines words that push the two values on the stack when run:

: cons create , , does> dup 0 @ swap 1 @ ;

Define a word that creates a one-dimensional array of cells of a given size:

: array create cells allot ;

Use it:

10 array xs  500 xs 3 !  xs 3 @   \ retrieves the 500

For multi-dimensional arrays and for things like dynamically allocating conses, we probably need pointer arithmetic. But we can bounds-check the pointer arithmetic with fat pointers. That allows us to say, for example:

0 value this
: 2darray create dup , * cells allot  \ save Y-dimension
   does> to this  this 0 @ * cells this + 1+ ;

This lets us get a pointer to the Nth row of the 2darray, and we can then use that row as a normal 1-D array, but with weaker bounds-checking:

32 64 2darray tile  5 tile  \ get pointer to row 5 of 32
100 @    \ will work even though the row is smaller than that

Similarly, this allows us to allocate cons cells from an arena that we can later garbage-collect. Address arithmetic within the arena is fine; trying to index out of your arena will fail.

You can also have allocate if you want to be able to create new “segments” at run-time.

One problem I’ve run into with the similar semantics in C is that it’s impossible to write memmove.

Topics