Commit | Line | Data |
---|---|---|
92a92075 AT |
1 | # Overview # |
2 | ||
3 | This folder contains a library of useful functions written in VVhitespace. | |
48f88489 AT |
4 | They are intended to remove the tedium of frequently repeated patterns while |
5 | remaining short enough to easily comprehend and modify. | |
6 | ||
7 | For those eager to jump right in, all functions have comments in the source | |
8 | code containing a text description as well as both call and return stacks. | |
9 | Simply `#include` the relevant file, setup your call stack per the | |
10 | documentation and then `JSR` to the stdlib function of your choice. | |
11 | ||
12 | Some functions, like `deepdup`, `stackrotate` and `stackrotatereverse`, ease | |
13 | stack manipulations by allowing easy access to elements deep on the stack. | |
14 | Similarly, `slurp` and `spew` help move bulk data between the stack and heap. | |
15 | ||
16 | User interactions were also targeted. The included `printf` function provides a | |
6fc33bfd AT |
17 | variety of substitutions to ease user interactions. For user input, |
18 | `get user string` and `atoi` allow easy creation of basic user interfaces. | |
48f88489 AT |
19 | |
20 | The library includes a variety of bitwise logic functions as well as heap | |
21 | manipulation functions and a handful of math functions including a random | |
22 | number generator. | |
23 | ||
24 | ||
25 | # Instructions # | |
26 | ||
27 | Before we can use this library, we must `#include` it in our program. Looking | |
28 | at the "Entry Points" table below, if we wanted to call `deepdup` we would need | |
29 | to `#include <stack.pvvs>` in our code, but where? | |
30 | ||
31 | Recall that VVhitespace processes our code from top to bottom. Thus, it is | |
32 | always safe to `#include` files at the bottom, after our program's text. This | |
33 | way the files are included in our source code but won't be accidentally | |
34 | executed 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 | ||
45 | What about that `PUSH 2` instruction that is an argument to `deepdup`? If we | |
46 | check `stack.pvvs`, we will find the following comment above the `deepdup` | |
47 | function: | |
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 | ||
70 | From the "Call Stack" example, we can see that `deepdup` requires a `dupdepth` | |
71 | argument on the TOS. Since we wanted to duplicate the second item on the stack, | |
72 | we used `PUSH 2` immediately before calling `deepdup`. | |
73 | ||
74 | In addition to the call stack, the code comments also show you what to expect | |
75 | on the return stack, as well as any other information you might need in order | |
76 | to use the function. | |
77 | ||
78 | ||
79 | # Resource Reservations # | |
32c440bf | 80 | |
32c440bf | 81 | |
48f88489 | 82 | ## Entry Points ## |
32c440bf AT |
83 | |
84 | The following labels are entry points to stdlib functions. Read the | |
85 | header 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 |
140 | Since all labels share a global namespace, the standard library makes the |
141 | following 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 | ||
151 | The first 16 heap addresses (`0-15`) are reserved when using the stdlib. | |
6fc33bfd AT |
152 | Within that reservation, `heap[0]` is used by `random` and the block |
153 | `heap[1]`-`heap[15]` by the stack rotation subroutines which time-share | |
48f88489 AT |
154 | pseudo-registers between the various stdlib subroutines. |
155 | ||
6fc33bfd | 156 | By convention, chosen since no function other than `random` should use `heap[0],` |
48f88489 AT |
157 | functions which return a pointer will use the address `0` to represent a `NULL` |
158 | pointer. | |
159 | ||
160 | ||
32c440bf AT |
161 | # Misc # |
162 | ||
2c2764b7 | 163 | |
48f88489 AT |
164 | ## Bitwise Logic Constants ## |
165 | ||
166 | Be cautious when pushing constants in your code for use as bit arrays. Due to | |
167 | the mismatch between the VVhitespace language's sign-magnitude representation | |
168 | of integers and the interpreter's internal twos-complement representation, bit | |
169 | arrays with a leading `1` (i.e. negative numbers) may appear quite different | |
6a0f845c | 170 | than expected in your source code. |
48f88489 AT |
171 | |
172 | For 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 | ||
178 | By default, the stdlib uses the first 16 heap addresses. All heap access (other | |
6fc33bfd | 179 | than `heap[0]` as a seed) occurs through `stackrotate` and `stackrotatereverse`. |
2c2764b7 AT |
180 | Edit these functions to increase the stdlib's heap reservation. |
181 | ||
182 | The remainder of the stdlib is written to automatically use the new allocation. | |
183 | Functions like `printf`, for example, allow more substitutions when the heap | |
184 | allocation is increased. | |
48f88489 AT |
185 | |
186 | ||
187 | ## Private Label Space ## | |
188 | ||
189 | By convention, each public stdlib label will have 8 bits of private label space | |
190 | associated 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 | ||
199 | Strings 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 | |
201 | addressable. | |
202 | ||
203 | All strings terminate with an ASCII NUL (`\0`) character. | |
204 | ||
205 | ||
206 | ## Using the C Preprocessor ## | |
207 | ||
208 | The standard library uses ordinary include guards of the following form: | |
209 | ||
210 | #ifndef FOO | |
211 | #define FOO | |
212 | ... | |
213 | #endif | |
214 | ||
215 | This means you can `#include` a file multiple times without problems. To ease | |
216 | refactoring, I recommend writing the `#include` statements per-function rather | |
217 | than per-file. See the stdlib for examples. | |
218 | ||
219 | Use of the C Preprocessor also means its syntax must be respected as though the | |
220 | file were C rather than VVhitespace. For example, use of a single apostrophe in | |
221 | a VVhitespace comment (e.g. don't) throws out a warning: | |
222 | ||
223 | warning: missing terminating ' character [-Winvalid-pp-token] | |
224 | ||
225 | You won't run into any errors if you copy the stdlib's format but if you | |
226 | stray I'm sure one could concoct some combination of characters that is both a | |
227 | comment in VVhitespace and a hard error for `cpp`. | |
228 | ||
229 | ||
230 | ## Whitespace Compatibility ## | |
231 | ||
232 | Most of this library will run on most Whitespace interpreters. Some parts, like | |
233 | the bitwise logic functions, make assumptions about the representation of | |
234 | integers in the interpreter that may be less portable than the rest of the | |
235 | library. | |
236 | ||
237 | Regardless, tests are included for every stdlib function and can be run though | |
238 | the Whitespace interpreter of your choice to determine compatibility. | |
239 |