From 48f884892a9cb24c1be8bb0d8f5f5f6851c03bd5 Mon Sep 17 00:00:00 2001 From: Aaron Taylor Date: Mon, 30 Mar 2020 00:36:44 -0700 Subject: [PATCH] First draft of a real README for the VVS stdlib. Also corrected license info in stdlib headers. --- stdlib/README.md | 195 +++++++++++++++++++++++++++++++++++++------- stdlib/convert.pvvs | 3 + stdlib/debug.pvvs | 3 + stdlib/heap.pvvs | 3 + stdlib/logic.pvvs | 3 + stdlib/math.pvvs | 3 + stdlib/stack.pvvs | 3 + stdlib/stdio.pvvs | 3 + stdlib/string.pvvs | 3 + 9 files changed, 190 insertions(+), 29 deletions(-) diff --git a/stdlib/README.md b/stdlib/README.md index efa3220..32b5091 100644 --- a/stdlib/README.md +++ b/stdlib/README.md @@ -1,33 +1,88 @@ # 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`. This also means -`cpp` syntax must be respected. - -# Reservations # +They are intended to remove the tedium of frequently repeated patterns while +remaining short enough to easily comprehend and modify. + +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. + +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. + +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. + +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 ` 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 + +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. + + +# Resource Reservations # Since all labels share a global namespace, the standard library makes the following reservations: -## Label ## - 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, functions which return a pointer will use the address `0` to -represent a `NULL` pointer. - -# 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. @@ -55,7 +110,7 @@ header comment for each function to learn the call and return stack. 100xxx - string functions 100000 ----- strlen (string.pvvs) 100001 ----- isdigit (string.pvvs) - 100010 ----- get_user_string (string.pvvs) + 100010 ----- get user string (string.pvvs) 101xxx - logic functions 101000 ----- not (logic.pvvs) 101001 ----- and (logic.pvvs) @@ -81,16 +136,43 @@ header comment for each function to learn the call and return stack. 1000100 ----- print string from stack (stdio.pvvs) 1000101 ----- print string from heap (stdio.pvvs) + +## Labels ## + + 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 # -## Private Label Space ## -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 +then 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`, not +`SSSTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTN` +(2^65-1). - 00001000 xxxxxxxx - for use by 1000 - 00001001 xxxxxxxx - for use by 1001 - ...etc ## Extending Heap Reservation ## @@ -101,3 +183,58 @@ 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 + + +## 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. + diff --git a/stdlib/convert.pvvs b/stdlib/convert.pvvs index e20c809..592af9a 100644 --- a/stdlib/convert.pvvs +++ b/stdlib/convert.pvvs @@ -1,3 +1,6 @@ +@ (c) 2020 Aaron Taylor +@ See LICENSE.txt file for copyright and license details. + #ifndef VVS_STDLIB_CONVERT #define VVS_STDLIB_CONVERT diff --git a/stdlib/debug.pvvs b/stdlib/debug.pvvs index d272b6c..ea1bd5c 100644 --- a/stdlib/debug.pvvs +++ b/stdlib/debug.pvvs @@ -1,3 +1,6 @@ +@ (c) 2020 Aaron Taylor +@ See LICENSE.txt file for copyright and license details. + #ifndef VVS_STDLIB_DEBUG #define VVS_STDLIB_DEBUG diff --git a/stdlib/heap.pvvs b/stdlib/heap.pvvs index 4626995..81fe610 100644 --- a/stdlib/heap.pvvs +++ b/stdlib/heap.pvvs @@ -1,3 +1,6 @@ +@ (c) 2020 Aaron Taylor +@ See LICENSE.txt file for copyright and license details. + #ifndef VVS_STDLIB_HEAP #define VVS_STDLIB_HEAP diff --git a/stdlib/logic.pvvs b/stdlib/logic.pvvs index 8ac7a39..a69cd3a 100644 --- a/stdlib/logic.pvvs +++ b/stdlib/logic.pvvs @@ -1,3 +1,6 @@ +@ (c) 2020 Aaron Taylor +@ See LICENSE.txt file for copyright and license details. + #ifndef VVS_STDLIB_LOGIC #define VVS_STDLIB_LOGIC diff --git a/stdlib/math.pvvs b/stdlib/math.pvvs index a72203f..90a3666 100644 --- a/stdlib/math.pvvs +++ b/stdlib/math.pvvs @@ -1,3 +1,6 @@ +@ (c) 2020 Aaron Taylor +@ See LICENSE.txt file for copyright and license details. + #ifndef VVS_STDLIB_MATH #define VVS_STDLIB_MATH diff --git a/stdlib/stack.pvvs b/stdlib/stack.pvvs index 0403044..8ed5e9d 100644 --- a/stdlib/stack.pvvs +++ b/stdlib/stack.pvvs @@ -1,3 +1,6 @@ +@ (c) 2020 Aaron Taylor +@ See LICENSE.txt file for copyright and license details. + #ifndef VVS_STDLIB_STACK #define VVS_STDLIB_STACK diff --git a/stdlib/stdio.pvvs b/stdlib/stdio.pvvs index 15cbb2c..26171e6 100644 --- a/stdlib/stdio.pvvs +++ b/stdlib/stdio.pvvs @@ -1,3 +1,6 @@ +@ (c) 2020 Aaron Taylor +@ See LICENSE.txt file for copyright and license details. + #ifndef VVS_STDLIB_STDIO #define VVS_STDLIB_STDIO diff --git a/stdlib/string.pvvs b/stdlib/string.pvvs index e3135c2..f108539 100644 --- a/stdlib/string.pvvs +++ b/stdlib/string.pvvs @@ -1,3 +1,6 @@ +@ (c) 2020 Aaron Taylor +@ See LICENSE.txt file for copyright and license details. + #ifndef VVS_STDLIB_STRING #define VVS_STDLIB_STRING -- 2.20.1