From 91ca83e3122c9f63e6331dbfe04004f1ab04718e Mon Sep 17 00:00:00 2001 From: Bryan English Date: Thu, 5 Feb 2026 17:00:41 -0500 Subject: [PATCH] lang description --- rel-lang/docs/language_overview.md | 68 ++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 rel-lang/docs/language_overview.md diff --git a/rel-lang/docs/language_overview.md b/rel-lang/docs/language_overview.md new file mode 100644 index 0000000..cb94446 --- /dev/null +++ b/rel-lang/docs/language_overview.md @@ -0,0 +1,68 @@ +# Language Overview + +**Sorel** is a concatenative stack language, similar in form to Forth. +Unlike most Forth variants, it's strictly a compiled language, with no interpreter provided at run time. +Today, it targets only 64-bit RISC-V architectures. +It has a small standard library, that does not use libc. +Instead it makes system calls directly, currently only supporting Linux. + +Like in Forth, code is written in Reverse Polish Notation. +Every "word" corresponds to a function that manipulates the stack in some way. +Unlike in Forth, strings count as a single word, and are written much like they are in C. + +## The Stack + +All Forths have a stack, and Sorel is no exception. +Since Sorel's function calls follow the C ABI, there's no need for the traditional Forth return stack. +There's only the data stack. +Much like call stacks, it grows downward. +Each stack cell is exactly 64 bits wide, regardless of type. +For smaller types, the values are padded with 0s. +Note that RISC-V systems are little-endian. + +## Type System + +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. + +Values themselves don't have types. +Operations have types. +In other words, values are always just bits in memory, and only have a "type" when they are treated as such by a word manipulating the stack or heap memory. + +> This is, of course, very dangerous. +> A planned improvement is to add static type-checking support via type comments. + +Complex types like arrays and structs don't exist (yet), but they can be maniplulated through direct memory operations. +See `std:mem` for details. + +String literals, when pushed onto the stack, appear as pointers to null-terminated UTF-8 representations of them. +Other than that, strings are just like any other complex type, in that there's no special support (yet). + +## Module System + +Sorel supports import statements of the form `import "./relative/path/to/file.sorel"`, with the exception of standard library imports (see below). +Note that `import` is _not_ executed at run-time, and instead is evaluated as a pre-processing step. +To make that clear, note that the import specifier comes _after_ the keyword. +This indicates that `import` is not operating on a value in the stack. + +Similarly, words may be exported via `export word_name`. +Only words deliberately exported will be made available to other files via `import`. + +Word invocations _outside_ word defintions will be executed as the program's entrypoint function (i.e. "main"), but _only_ if those invocations are in the entrypoint module. +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. + +## Built-in Words + + + +## Standard Library + +Built-in words are insufficient to create most programs. +A standard library is provided with exported words to enable higher level operations. +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. +* **`std:out`** : This module contains words to print numbers and strings to stdout. -- 2.43.0