Snusp Calling Conventions

This is an attempt to specify a set of calling conventions for use in Modular SnuspLanguage in order to maximize interoperability between different SNUSP libraries and applications.

Each row of data memory in SNUSP (only programs written in Bloated SNUSP can access multiple rows of data) is called a strip, and each strip corresponds roughly to a C stack.


Allocate Rightwards

A subroutine should always assume that the data pointer could be at the leftmost cell in the strip. This ensures that the subroutine is isolated from all local data of earlier-called subroutines, and that it may be called regardless of the horizontal position of the data pointer.

Conversely, a caller should always assume that any data present to the right of the cell at which the data pointer was at the time of the call will not only be corrupted by the subroutine, but will most likely cause it to malfunction.


Leave Output where Input Was Given

Before calling a subroutine, the data pointer should be moved to the start of its input parameters. Likewise, the return value of a subroutine should always be left in the cell that the data pointer was at on entry, and, if the value is complex, any number of the following ones.


Clean Your Own Dirt

Each subroutine need not zero out its allocated memory before using it; this is the responsibility of the caller. However, before a subroutine returns it must clean up any and all junk left in the memory area to the right of its return value.


Use Only One Memory Strip

Do not touch any memory above or below the cell that the data pointer was at on entry. In fact, do not even move the data pointer upwards since this could invoke undefined behavior. The other memory strips are reserved for use in multi-threaded programs, and in such cases all threads which communicate via a shared heap needs to be coupled to the application. This is because in order to know the current offset to a designated heap, one needs to know both the exact memory layout and what thread is currently executing.

What would be needed in order for a general-purpose library to be able to keep static data and remain decoupled to the application?

One way would be to embed in the library cable what can be called a hook wire, and require the application to connect this wire to a subroutine which is responsible for moving the data pointer from a certain unspecified "origin cell" to the start of the library's static data block. Thus, to properly invoke a library routine that needs access to static data, a thread would need to

  1. move the data pointer to the origin cell,
  2. make the library call, and finally
  3. move the data pointer back to the thread-local strip.


The point of these rules is to enforce stack behavior from the data array. These rules should be familiar to those who program on open stacks, such as found in ForthLanguage. The same rules also usefully apply to BrainfuckLanguage and its derivations.

The main pre- and post-condition in my opinion is to have all cells to the right of the data-pointer be zero between calls.


See: SnuspLanguage


EditText of this page (last edited January 31, 2005) or FindPage with title or text search