All values are treated as 64-bit unsigned integers unles otherwise indicated.
Number literals can provide type information after a colon.
For example, `-37:i32` will add -37 as a signed 32-bit integer onto the stack.
+Similarly, `45.5:f64` will add 45.5 as a 64-bit float, and `123:u8` will add 123 as an unsigned 8-bit integer.
+Numbers respect the system endianness (little-endian).
Values themselves don't have types.
Operations have types.
See `std:mem` for details.
String literals, when pushed onto the stack, appear as pointers to null-terminated UTF-8 representations of them.
+They are added to read-only memory in the binary, so they cannot be modified.
+To modify them, copy them to heap memory first.
Other than that, strings are just like any other complex type, in that there's no special support (yet).
## Module System
This means any module can have word invocations inside it that aren't executed when it's not the entrypoint.
This is useful for writing tests.
+## Interacting with C or Other Native Code
+
+Sorel supports calling other native code when it's statically linked into the same binary.
+Declare an externally-linked function using `extern function_name`.
+Then, you can call it like any other Sorel word.
+To pass arguments, simply put them on the stack in the order that they appear in the function signature.
+Be careful with types.
+The return value is added to the stack once the function returns.
+
+For the moment, dynamic libraries cannot be loaded.
+Exposing Sorel functions to C is also not currently supported, and Sorel _must_ control the entrypoint/`main()`/`_start`.
+
## Built-in Words
-<!-- TODO -->
+* `dup`
+ * Duplicate the top of the stack onto itself.
+* `swap`
+ * Swap the top two stack items.
+* `drop`
+ * Remove the top item of the stack, ignoring its value.
+* `over`
+ * Copy the item underneath the top stack item to the top of the stack.
+* `rot`
+ * Move the top item on the stack two cells down.
+* `sp`
+ * Put a pointer to the current top of the stack on top of the stack.
+* `stackbottom`
+ * Put a pointer to the bottom of the stack on top of the stack.
+* `if`/`else`/`endif`
+ * Operate how they do in other languages. These words delimit the "blocks". `if` removes the top of the stack and evaluates that as the condition. Remember, `0` is true and all other values are false.
+* `loop`/`endloop`
+ * These words delimit a loop block. At `loop`, and on each iteration, the top of the stack is removed and evaluated, and if true, exits the loop.
+* `call`
+ * Pop a function pointer off the top of the stack and call it. Assumes a Sorel function, not a C extern.
+* `=`, `<`, `>`,
+ * Pop two values off the stack and compare, putting a boolean back on the stack. Remember, `0` is true, and all other values are false.
+* `+`, `-`, `*`, `/`, `%` (mod), `|` (bitwise OR) _(TODO add remaining operators)_
+ * Arithmetic operators. Pop two values off the stack and operate on them in the order they're added to the stack. Push the result back onto the stack.
+* `sys0`, `sys1`, `sys2`, ..., `sys6`
+ * Make a system call. The number in the word indicates the number of arguments. Call this the same way you'd call an extern.
+
+In order to use `call`, you'll need to get a function pointer.
+These can be retrieved for a given function by prefixing it with an apostrophe `'`.
+For eample, to put a pointer to `foo` onto the stack, do `'foo`.
## Standard Library
The following standard library modules are provided, and can be imported by specificying their name as the import specifier:
* **`std:mem`** : This module contains words to allocate and free memory.
+ * `alloc ( byte-count -- addr )`, `free ( addr -- )`
+ * This is a memory allocator. Currently, `alloc` normalizes byte-count to the system memory page size. In the future, it will be accurate to the number of bytes asked for.
+ * `memcopy ( addr-from addr-to byte-count -- )`
+ * Copies data in memoty from `addr-from` to `addr-to`, with length `byte-count`.
* **`std:out`** : This module contains words to print numbers and strings to stdout.
+ * `putn`
+ * Print the top of the stack, as an unsigned 64-bit integer, to stdout, without manipulating the stack.
+ * `puts`
+ * Print the null-terminated string at the memory address that's on the top of the stack, without manipulating the stack.
+ * `putstack`
+ * For debugging purposes, print out the entire stack, without manipulating it.
+* **`std:process`** : This module contains words to work with the current process.
+ * `exit`
+ * Exits the process, using the top of the stack as the exit code.
+* **`std:string`** : This module contains words to work with strings.
+ * `strlen`
+ * Replaces a pointer to a null-terminated string at the top of the stack with its length in bytes.