Fixed minor typos.
[vvhitespace] / stdlib / README.md
CommitLineData
92a92075
AT
1# Overview #
2
3This folder contains a library of useful functions written in VVhitespace.
48f88489
AT
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 #
32c440bf 80
32c440bf 81
48f88489 82## Entry Points ##
32c440bf
AT
83
84The following labels are entry points to stdlib functions. Read the
85header comment for each function to learn the call and return stack.
86
3625ff3a 87 000xxx - reserved
23d17247
AT
88 001xxx - core functions
89 1000 ----- printf (stdio.pvvs)
90 1001 ----- print number from stack (stdio.pvvs)
91 1010 ----- stackrotate (stack.pvvs)
a67867ae 92 1011 ----- stackrotatereverse (stack.pvvs)
f0499c77 93 1100 ----- deepdup (stack.pvvs)
3625ff3a 94 010xxx - math functions
2612f47f 95 10000 ----- random (math.pvvs)
3625ff3a 96 10001 ----- absolute value (math.pvvs)
37372ed0 97 10010 ----- greatest common divisor (math.pvvs)
d5a0b337 98 10011 ----- fastrand (math.pvvs)
3695b659
AT
99 011xxx - heap functions
100 11000 ----- memset (heap.pvvs)
3d75b928 101 11001 ----- memcpy (heap.pvvs)
d63de3fa 102 11010 ----- memrand (heap.pvvs)
87d27426 103 11011 ----- memcmp (heap.pvvs)
fd04fb41 104 11100 ----- memsrch (heap.pvvs)
bb21580a
AT
105 11101 ----- <empty>
106 11110 ----- slurp (heap.pvvs)
107 11111 ----- spew (heap.pvvs)
ae1f85a1
AT
108 100xxx - string functions
109 100000 ----- strlen (string.pvvs)
0e0d0a4a 110 100001 ----- isdigit (string.pvvs)
48f88489 111 100010 ----- get user string (string.pvvs)
0c56152e
AT
112 101xxx - logic functions
113 101000 ----- not (logic.pvvs)
114 101001 ----- and (logic.pvvs)
115 101010 ----- or (logic.pvvs)
116 101011 ----- xor (logic.pvvs)
117 101100 ----- rshift (logic.pvvs)
118 101101 ----- lshift (logic.pvvs)
1a56830d 119 110xxx - conversion functions
b6bea2cf 120 110000 ----- atoi (convert.pvvs)
1a56830d
AT
121 111xxx - debug functions
122 111000 ----- dump heap (debug.pvvs)
ae1f85a1 123 111001 ----- dump stack (debug.pvvs)
9f7f68e5
AT
124 111010 ----- print sign (debug.pvvs)
125 111011 ----- print magnitude (debug.pvvs)
126 111100 ----- print string (debug.pvvs)
4fba07dc 127 111101 ----- print signed number (debug.pvvs)
aa1914c3 128 111110 ----- stdlib version (debug.pvvs)
3625ff3a 129 1xxxxxx - reserved for less common entry points
e0d5136c 130 1000000 ----- lowbitand (logic.pvvs)
75098baa 131 1000001 ----- <empty>
ae1f85a1
AT
132 1000010 ----- print sign of number (stdio.pvvs)
133 1000011 ----- print magnitude of number (stdio.pvvs)
b8b65c17
AT
134 1000100 ----- print string from stack (stdio.pvvs)
135 1000101 ----- print string from heap (stdio.pvvs)
32c440bf 136
48f88489
AT
137
138## Labels ##
139
fec66686
AT
140Since all labels share a global namespace, the standard library makes the
141following reservations:
142
48f88489
AT
143 00000000 0xxxxxxx - reserved for stdlib function entry points
144 00000000 1xxxxxxx - available for use in user programs
145 0xxxxxxx xxxxxxxx - reserved for private use by stdlib
146 1xxxxxxx xxxxxxxx - available for use in user programs
147
148
149## Heap and Pointers ##
150
151The first 16 heap addresses (`0-15`) are reserved when using the stdlib.
152Within that reservation, heap[0] is used by `random` and the block
153heap[1]-heap[15] by the stack rotation subroutines which time-share
154pseudo-registers between the various stdlib subroutines.
155
156By convention, chosen since no function other than `random` should use heap[0],
157functions which return a pointer will use the address `0` to represent a `NULL`
158pointer.
159
160
32c440bf
AT
161# Misc #
162
2c2764b7 163
48f88489
AT
164## Bitwise Logic Constants ##
165
166Be cautious when pushing constants in your code for use as bit arrays. Due to
167the mismatch between the VVhitespace language's sign-magnitude representation
168of integers and the interpreter's internal twos-complement representation, bit
169arrays with a leading `1` (i.e. negative numbers) may appear quite different
6a0f845c 170than expected in your source code.
48f88489
AT
171
172For example, to push a 64-bit array of all `1`'s on to the stack we must push
97f15363 173`SSTTN`, or `-1`.
32c440bf 174
2c2764b7
AT
175
176## Extending Heap Reservation ##
177
178By default, the stdlib uses the first 16 heap addresses. All heap access (other
179than heap[0] as a seed) occurs through `stackrotate` and `stackrotatereverse`.
180Edit these functions to increase the stdlib's heap reservation.
181
182The remainder of the stdlib is written to automatically use the new allocation.
183Functions like `printf`, for example, allow more substitutions when the heap
184allocation is increased.
48f88489
AT
185
186
187## Private Label Space ##
188
189By convention, each public stdlib label will have 8 bits of private label space
190associated with it, formed as follows:
191
192 00001000 xxxxxxxx - for use by 1000
193 00001001 xxxxxxxx - for use by 1001
194 ...etc
195
196
197## Strings ##
198
199Strings in VVhitespace are stored as one character per 64-bit word since the
200`LOAD` and `STORE` instructions are word length and the heap is word
201addressable.
202
203All strings terminate with an ASCII NUL (`\0`) character.
204
205
206## Using the C Preprocessor ##
207
208The standard library uses ordinary include guards of the following form:
209
210 #ifndef FOO
211 #define FOO
212 ...
213 #endif
214
215This means you can `#include` a file multiple times without problems. To ease
216refactoring, I recommend writing the `#include` statements per-function rather
217than per-file. See the stdlib for examples.
218
219Use of the C Preprocessor also means its syntax must be respected as though the
220file were C rather than VVhitespace. For example, use of a single apostrophe in
221a VVhitespace comment (e.g. don't) throws out a warning:
222
223 warning: missing terminating ' character [-Winvalid-pp-token]
224
225You won't run into any errors if you copy the stdlib's format but if you
226stray I'm sure one could concoct some combination of characters that is both a
227comment in VVhitespace and a hard error for `cpp`.
228
229
230## Whitespace Compatibility ##
231
232Most of this library will run on most Whitespace interpreters. Some parts, like
233the bitwise logic functions, make assumptions about the representation of
234integers in the interpreter that may be less portable than the rest of the
235library.
236
237Regardless, tests are included for every stdlib function and can be run though
238the Whitespace interpreter of your choice to determine compatibility.
239