One small formatting correction for the stdlib README.
[vvhitespace] / stdlib / README.md
... / ...
CommitLineData
1# Overview #
2
3This folder contains a library of useful functions written in VVhitespace.
4They are intended to remove the tedium of frequently repeated patterns while
5remaining short enough to easily comprehend and modify.
6
7For those eager to jump right in, all functions have comments in the source
8code containing a text description as well as both call and return stacks.
9Simply `#include` the relevant file, setup your call stack per the
10documentation and then `JSR` to the stdlib function of your choice.
11
12Some functions, like `deepdup`, `stackrotate` and `stackrotatereverse`, ease
13stack manipulations by allowing easy access to elements deep on the stack.
14Similarly, `slurp` and `spew` help move bulk data between the stack and heap.
15
16User interactions were also targeted. The included `printf` function provides a
17variety of substitutions to ease user interactions. For user input, `get user
18string` and `atoi` allow easy creation of basic user interfaces.
19
20The library includes a variety of bitwise logic functions as well as heap
21manipulation functions and a handful of math functions including a random
22number generator.
23
24
25# Instructions #
26
27Before we can use this library, we must `#include` it in our program. Looking
28at the "Entry Points" table below, if we wanted to call `deepdup` we would need
29to `#include <stack.pvvs>` in our code, but where?
30
31Recall that VVhitespace processes our code from top to bottom. Thus, it is
32always safe to `#include` files at the bottom, after our program's text. This
33way the files are included in our source code but won't be accidentally
34executed by the interpreter. For example:
35
36 @ Put two elements on the stack.
37 SSSTTTTSTSSN | PUSH 244
38 SSSTN | PUSH 1
39 @ Duplicate the deeper element.
40 SSSTSN | PUSH 2 (argument to deepdup)
41 NSTTTSSN | JSR > 1100 (deepdup)
42 NNN | DIE
43 #include <stack.pvvs>
44
45What about that `PUSH 2` instruction that is an argument to `deepdup`? If we
46check `stack.pvvs`, we will find the following comment above the `deepdup`
47function:
48
49 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
50 @ Name:
51 @ deepdup
52 @ Description:
53 @ Duplicates an item deep on the stack, placing the duplicate on TOS.
54 @ By default, maximum depth is 13.
55 @ True maximum depth is (max depth of stackrotate & stackrotatereverse)-1.
56 @ Call Stack:
57 @ stack word n
58 @ ...
59 @ stack word 1
60 @ dupdepth <-- TOS
61 @ Return Stack: (dupdepth=3)
62 @ stack word n
63 @ ...
64 @ stack word 1
65 @ copy of stack word 3 <-- TOS
66 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
67 NSSVTTSSN | Mark: 1100 (deepdup)
68 ...
69
70From the "Call Stack" example, we can see that `deepdup` requires a `dupdepth`
71argument on the TOS. Since we wanted to duplicate the second item on the stack,
72we used `PUSH 2` immediately before calling `deepdup`.
73
74In addition to the call stack, the code comments also show you what to expect
75on the return stack, as well as any other information you might need in order
76to use the function.
77
78
79# Resource Reservations #
80
81Since all labels share a global namespace, the standard library makes the
82following reservations:
83
84
85## Entry Points ##
86
87The following labels are entry points to stdlib functions. Read the
88header comment for each function to learn the call and return stack.
89
90 000xxx - reserved
91 001xxx - core functions
92 1000 ----- printf (stdio.pvvs)
93 1001 ----- print number from stack (stdio.pvvs)
94 1010 ----- stackrotate (stack.pvvs)
95 1011 ----- stackrotatereverse (stack.pvvs)
96 1100 ----- deepdup (stack.pvvs)
97 010xxx - math functions
98 10000 ----- random (math.pvvs)
99 10001 ----- absolute value (math.pvvs)
100 10010 ----- greatest common divisor (math.pvvs)
101 011xxx - heap functions
102 11000 ----- memset (heap.pvvs)
103 11001 ----- memcpy (heap.pvvs)
104 11010 ----- memrand (heap.pvvs)
105 11011 ----- memcmp (heap.pvvs)
106 11100 ----- memsrch (heap.pvvs)
107 11101 ----- <empty>
108 11110 ----- slurp (heap.pvvs)
109 11111 ----- spew (heap.pvvs)
110 100xxx - string functions
111 100000 ----- strlen (string.pvvs)
112 100001 ----- isdigit (string.pvvs)
113 100010 ----- get user string (string.pvvs)
114 101xxx - logic functions
115 101000 ----- not (logic.pvvs)
116 101001 ----- and (logic.pvvs)
117 101010 ----- or (logic.pvvs)
118 101011 ----- xor (logic.pvvs)
119 101100 ----- rshift (logic.pvvs)
120 101101 ----- lshift (logic.pvvs)
121 110xxx - conversion functions
122 110000 ----- atoi (convert.pvvs)
123 111xxx - debug functions
124 111000 ----- dump heap (debug.pvvs)
125 111001 ----- dump stack (debug.pvvs)
126 111010 ----- print sign (debug.pvvs)
127 111011 ----- print magnitude (debug.pvvs)
128 111100 ----- print string (debug.pvvs)
129 111101 ----- print signed number (debug.pvvs)
130 111110 ----- stdlib version (debug.pvvs)
131 1xxxxxx - reserved for less common entry points
132 1000000 ----- lowbitand (logic.pvvs)
133 1000001 ----- <empty>
134 1000010 ----- print sign of number (stdio.pvvs)
135 1000011 ----- print magnitude of number (stdio.pvvs)
136 1000100 ----- print string from stack (stdio.pvvs)
137 1000101 ----- print string from heap (stdio.pvvs)
138
139
140## Labels ##
141
142 00000000 0xxxxxxx - reserved for stdlib function entry points
143 00000000 1xxxxxxx - available for use in user programs
144 0xxxxxxx xxxxxxxx - reserved for private use by stdlib
145 1xxxxxxx xxxxxxxx - available for use in user programs
146
147
148## Heap and Pointers ##
149
150The first 16 heap addresses (`0-15`) are reserved when using the stdlib.
151Within that reservation, heap[0] is used by `random` and the block
152heap[1]-heap[15] by the stack rotation subroutines which time-share
153pseudo-registers between the various stdlib subroutines.
154
155By convention, chosen since no function other than `random` should use heap[0],
156functions which return a pointer will use the address `0` to represent a `NULL`
157pointer.
158
159
160# Misc #
161
162
163## Bitwise Logic Constants ##
164
165Be cautious when pushing constants in your code for use as bit arrays. Due to
166the mismatch between the VVhitespace language's sign-magnitude representation
167of integers and the interpreter's internal twos-complement representation, bit
168arrays with a leading `1` (i.e. negative numbers) may appear quite different
169then expected in your source code.
170
171For example, to push a 64-bit array of all `1`'s on to the stack we must push
172`SSTTN`, or `-1`, not
173`SSSTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTN`, or
174`2^65-1`.
175
176
177## Extending Heap Reservation ##
178
179By default, the stdlib uses the first 16 heap addresses. All heap access (other
180than heap[0] as a seed) occurs through `stackrotate` and `stackrotatereverse`.
181Edit these functions to increase the stdlib's heap reservation.
182
183The remainder of the stdlib is written to automatically use the new allocation.
184Functions like `printf`, for example, allow more substitutions when the heap
185allocation is increased.
186
187
188## Private Label Space ##
189
190By convention, each public stdlib label will have 8 bits of private label space
191associated with it, formed as follows:
192
193 00001000 xxxxxxxx - for use by 1000
194 00001001 xxxxxxxx - for use by 1001
195 ...etc
196
197
198## Strings ##
199
200Strings in VVhitespace are stored as one character per 64-bit word since the
201`LOAD` and `STORE` instructions are word length and the heap is word
202addressable.
203
204All strings terminate with an ASCII NUL (`\0`) character.
205
206
207## Using the C Preprocessor ##
208
209The standard library uses ordinary include guards of the following form:
210
211 #ifndef FOO
212 #define FOO
213 ...
214 #endif
215
216This means you can `#include` a file multiple times without problems. To ease
217refactoring, I recommend writing the `#include` statements per-function rather
218than per-file. See the stdlib for examples.
219
220Use of the C Preprocessor also means its syntax must be respected as though the
221file were C rather than VVhitespace. For example, use of a single apostrophe in
222a VVhitespace comment (e.g. don't) throws out a warning:
223
224 warning: missing terminating ' character [-Winvalid-pp-token]
225
226You won't run into any errors if you copy the stdlib's format but if you
227stray I'm sure one could concoct some combination of characters that is both a
228comment in VVhitespace and a hard error for `cpp`.
229
230
231## Whitespace Compatibility ##
232
233Most of this library will run on most Whitespace interpreters. Some parts, like
234the bitwise logic functions, make assumptions about the representation of
235integers in the interpreter that may be less portable than the rest of the
236library.
237
238Regardless, tests are included for every stdlib function and can be run though
239the Whitespace interpreter of your choice to determine compatibility.
240