]> rethought.computer Git - sorel-lang.git/commitdiff
docs
authorBryan English <bryan@rethought.computer>
Thu, 19 Feb 2026 14:25:23 +0000 (09:25 -0500)
committerBryan English <bryan@rethought.computer>
Thu, 19 Feb 2026 14:25:31 +0000 (09:25 -0500)
docs/language_overview.md

index cb94446f9b347191a457d530b5dfe52adafdbd99..19ce351051fd51666c106f682d8692151f4d71a3 100644 (file)
@@ -25,6 +25,8 @@ Note that RISC-V systems are little-endian.
 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.
@@ -37,6 +39,8 @@ Complex types like arrays and structs don't exist (yet), but they can be maniplu
 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
@@ -53,9 +57,50 @@ Word invocations _outside_ word defintions will be executed as the program's ent
 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
 
@@ -65,4 +110,20 @@ It's implemented primarily by wrapping system calls.
 
 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.