Minor changes to README.
[vvhitespace] / stdlib / README.md
index 2bba7d5..b04f08e 100644 (file)
 # Overview #
 
 This folder contains a library of useful functions written in VVhitespace.
 # Overview #
 
 This folder contains a library of useful functions written in VVhitespace.
-Standard include guards are used with `cpp` to include the stdlib in user
-programs. For an example, see `examples/hello-stdlib`.
+They are intended to remove the tedium of frequently repeated patterns while
+remaining short enough to easily comprehend and modify.
 
 
-# Reservations #
+For those eager to jump right in, all functions have comments in the source
+code containing a text description as well as both call and return stacks.
+Simply `#include` the relevant file, setup your call stack per the
+documentation and then `JSR` to the stdlib function of your choice.
 
 
-Since all labels share a global namespace, the standard library makes the
-following reservations:
+Some functions, like `deepdup`, `stackrotate` and `stackrotatereverse`, ease
+stack manipulations by allowing easy access to elements deep on the stack.
+Similarly, `slurp` and `spew` help move bulk data between the stack and heap.
 
 
-## Label ##
+User interactions were also targeted. The included `printf` function provides a
+variety of substitutions to ease user interactions. For user input,
+`get user string` and `atoi` allow easy creation of basic user interfaces.
 
 
-    00000000 0xxxxxxx - reserved for stdlib function entry points
-    00000000 1xxxxxxx - unassigned
-    0xxxxxxx xxxxxxxx - reserved for private use by stdlib
-    1xxxxxxx xxxxxxxx - available for use in user programs
+The library includes a variety of bitwise logic functions as well as heap
+manipulation functions and a handful of math functions including a random
+number generator.
+
+
+# Instructions #
+
+Before we can use this library, we must `#include` it in our program.  Looking
+at the "Entry Points" table below, if we wanted to call `deepdup` we would need
+to `#include <stack.pvvs>` in our code, but where?
+
+Recall that VVhitespace processes our code from top to bottom. Thus, it is
+always safe to `#include` files at the bottom, after our program's text. This
+way the files are included in our source code but won't be accidentally
+executed by the interpreter. For example:
+
+    @ Put two elements on the stack.
+    SSSTTTTSTSSN    | PUSH 244
+    SSSTN           | PUSH 1
+    @ Duplicate the deeper element.
+    SSSTSN          | PUSH 2 (argument to deepdup)
+    NSTTTSSN        | JSR > 1100 (deepdup)
+    NNN             | DIE
+    #include <stack.pvvs>
+
+What about that `PUSH 2` instruction that is an argument to `deepdup`? If we
+check `stack.pvvs`, we will find the following comment above the `deepdup`
+function:
+
+    @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+    @ Name:
+    @   deepdup
+    @ Description:
+    @   Duplicates an item deep on the stack, placing the duplicate on TOS.
+    @   By default, maximum depth is 13.
+    @   True maximum depth is (max depth of stackrotate & stackrotatereverse)-1.
+    @ Call Stack:
+    @   stack word n
+    @   ...
+    @   stack word 1
+    @   dupdepth   <-- TOS
+    @ Return Stack: (dupdepth=3)
+    @   stack word n
+    @   ...
+    @   stack word 1
+    @   copy of stack word 3   <-- TOS
+    @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+    NSSVTTSSN               | Mark: 1100 (deepdup)
+    ...
+
+From the "Call Stack" example, we can see that `deepdup` requires a `dupdepth`
+argument on the TOS. Since we wanted to duplicate the second item on the stack,
+we used `PUSH 2` immediately before calling `deepdup`.
+
+In addition to the call stack, the code comments also show you what to expect
+on the return stack, as well as any other information you might need in order
+to use the function.
 
 
-## Heap ##
 
 
-    The first 256 heap addresses are reserved when using the stdlib.
+# Resource Reservations #
 
 
-# Entry Points #
+
+## Entry Points ##
 
 The following labels are entry points to stdlib functions. Read the
 header comment for each function to learn the call and return stack.
 
          000xxx - reserved
 
 The following labels are entry points to stdlib functions. Read the
 header comment for each function to learn the call and return stack.
 
          000xxx - reserved
-         001xxx - print functions
-           1000 ----- print string from stack       (stdio.pvvs)
-           1001 ----- print string from heap        (stdio.pvvs)
-           1010 ----- print number from stack       (stdio.pvvs)
+         001xxx - core functions
+           1000 ----- printf                        (stdio.pvvs)
+           1001 ----- print number from stack       (stdio.pvvs)
+           1010 ----- stackrotate                   (stack.pvvs)
+           1011 ----- stackrotatereverse            (stack.pvvs)
+           1100 ----- deepdup                       (stack.pvvs)
          010xxx - math functions
           10000 ----- random                        (math.pvvs)
           10001 ----- absolute value                (math.pvvs)
          010xxx - math functions
           10000 ----- random                        (math.pvvs)
           10001 ----- absolute value                (math.pvvs)
-         011xxx - unassigned
-         100xxx - unassigned
-         101xxx - unassigned
+          10010 ----- greatest common divisor       (math.pvvs)
+          10011 ----- fastrand                      (math.pvvs)
+         011xxx - heap functions
+          11000 ----- memset                        (heap.pvvs)
+          11001 ----- memcpy                        (heap.pvvs)
+          11010 ----- memrand                       (heap.pvvs)
+          11011 ----- memcmp                        (heap.pvvs)
+          11100 ----- memsrch                       (heap.pvvs)
+          11101 ----- <empty>
+          11110 ----- slurp                         (heap.pvvs)
+          11111 ----- spew                          (heap.pvvs)
+         100xxx - string functions
+         100000 ----- strlen                        (string.pvvs)
+         100001 ----- isdigit                       (string.pvvs)
+         100010 ----- get user string               (string.pvvs)
+         101xxx - logic functions
+         101000 ----- not                           (logic.pvvs)
+         101001 ----- and                           (logic.pvvs)
+         101010 ----- or                            (logic.pvvs)
+         101011 ----- xor                           (logic.pvvs)
+         101100 ----- rshift                        (logic.pvvs)
+         101101 ----- lshift                        (logic.pvvs)
          110xxx - conversion functions
          110xxx - conversion functions
+         110000 ----- atoi                          (convert.pvvs)
          111xxx - debug functions
          111000 ----- dump heap                     (debug.pvvs)
          111xxx - debug functions
          111000 ----- dump heap                     (debug.pvvs)
+         111001 ----- dump stack                    (debug.pvvs)
+         111010 ----- print sign                    (debug.pvvs)
+         111011 ----- print magnitude               (debug.pvvs)
+         111100 ----- print string                  (debug.pvvs)
+         111101 ----- print signed number           (debug.pvvs)
+         111110 ----- stdlib version                (debug.pvvs)
         1xxxxxx - reserved for less common entry points
         1xxxxxx - reserved for less common entry points
-        1000000 ----- print sign of number          (stdio.pvvs)
-        1000001 ----- print magnitude of number     (stdio.pvvs)
+        1000000 ----- lowbitand                     (logic.pvvs)
+        1000001 ----- <empty>
+        1000010 ----- print sign of number          (stdio.pvvs)
+        1000011 ----- print magnitude of number     (stdio.pvvs)
+        1000100 ----- print string from stack       (stdio.pvvs)
+        1000101 ----- print string from heap        (stdio.pvvs)
+
+
+## Labels ##
+
+Since all labels share a global namespace, the standard library makes the
+following reservations:
+
+    00000000 0xxxxxxx - reserved for stdlib function entry points
+    00000000 1xxxxxxx - available for use in user programs
+    0xxxxxxx xxxxxxxx - reserved for private use by stdlib
+    1xxxxxxx xxxxxxxx - available for use in user programs
+
+
+## Heap and Pointers ##
+
+The first 16 heap addresses (`0-15`) are reserved when using the stdlib.
+Within that reservation, `heap[0]` is used by `random` and the block
+`heap[1]`-`heap[15]` by the stack rotation subroutines which time-share
+pseudo-registers between the various stdlib subroutines.
+
+By convention, chosen since no function other than `random` should use `heap[0],`
+functions which return a pointer will use the address `0` to represent a `NULL`
+pointer.
+
 
 # Misc #
 
 
 # Misc #
 
-By convention, each public stdlib label will have 8 bits of
-private label space associated with it, formed as follows:
+
+## Bitwise Logic Constants ##
+
+Be cautious when pushing constants in your code for use as bit arrays. Due to
+the mismatch between the VVhitespace language's sign-magnitude representation
+of integers and the interpreter's internal twos-complement representation, bit
+arrays with a leading `1` (i.e. negative numbers) may appear quite different
+than expected in your source code.
+
+For example, to push a 64-bit array of all `1`'s on to the stack we must push
+`SSTTN`, or `-1`.
+
+
+## Extending Heap Reservation ##
+
+By default, the stdlib uses the first 16 heap addresses. All heap access (other
+than `heap[0]` as a seed) occurs through `stackrotate` and `stackrotatereverse`.
+Edit these functions to increase the stdlib's heap reservation.
+
+The remainder of the stdlib is written to automatically use the new allocation.
+Functions like `printf`, for example, allow more substitutions when the heap
+allocation is increased.
+
+
+## Private Label Space ##
+
+By convention, each public stdlib label will have 8 bits of private label space
+associated with it, formed as follows:
 
     00001000 xxxxxxxx - for use by 1000
     00001001 xxxxxxxx - for use by 1001
     ...etc
 
     00001000 xxxxxxxx - for use by 1000
     00001001 xxxxxxxx - for use by 1001
     ...etc
+
+
+## Strings ##
+
+Strings in VVhitespace are stored as one character per 64-bit word since the
+`LOAD` and `STORE` instructions are word length and the heap is word
+addressable.
+
+All strings terminate with an ASCII NUL (`\0`) character.
+
+
+## Using the C Preprocessor ##
+
+The standard library uses ordinary include guards of the following form:
+
+    #ifndef FOO
+    #define FOO
+    ...
+    #endif
+
+This means you can `#include` a file multiple times without problems. To ease
+refactoring, I recommend writing the `#include` statements per-function rather
+than per-file. See the stdlib for examples.
+
+Use of the C Preprocessor also means its syntax must be respected as though the
+file were C rather than VVhitespace. For example, use of a single apostrophe in
+a VVhitespace comment (e.g. don't) throws out a warning:
+
+    warning: missing terminating ' character [-Winvalid-pp-token]
+
+You won't run into any errors if you copy the stdlib's format but if you
+stray I'm sure one could concoct some combination of characters that is both a
+comment in VVhitespace and a hard error for `cpp`.
+
+
+## Whitespace Compatibility ##
+
+Most of this library will run on most Whitespace interpreters. Some parts, like
+the bitwise logic functions, make assumptions about the representation of
+integers in the interpreter that may be less portable than the rest of the
+library.
+
+Regardless, tests are included for every stdlib function and can be run though
+the Whitespace interpreter of your choice to determine compatibility.
+