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