reid-llvm/README.md

175 lines
6.1 KiB
Markdown
Raw Normal View History

# Reid-LLVM
2025-07-09 19:27:12 +02:00
Reid is a toy-language compiler I'm working on to learn LLVM (and compiler
development).
Reid only uses [llvm-sys](https://gitlab.com/taricorp/llvm-sys.rs), which
provide very minimal bindings from the LLVM C-API to Rust. `reid_llvm`-crate
contains the relevant abstraction to produce a more Rust'y API from that.
Much of the syntax in Reid is directly inspired by rust, but mostly it is driven
by simplicity.
2025-07-28 00:06:38 +02:00
Specifications and a bunch of [documentation for the language can be found
here](./documentation/).
2025-07-26 14:37:49 +02:00
2025-07-28 18:27:21 +02:00
An example of a real whole program (a CPU pathtracer) can be found [in
examples/cpu_raytracer.reid](./examples/cpu_raytracer.reid), go have a look!
2025-07-09 19:27:12 +02:00
Reid is currently able to (non-exhaustively):
2025-07-26 14:37:49 +02:00
- Do basic algebra binary and unary-operations (e.g. Add, Sub, Div, Mult, And,
Not)
2025-07-09 19:27:12 +02:00
- Resolve complex one-liners correctly using PEDMAS (e.g. `5 + 2 * 5 - 5 *
5` is calculated correctly)
2025-07-26 14:37:49 +02:00
- Handle borrows/derefs, pointers.
2025-07-09 19:27:12 +02:00
- Declare and call functions with varying parameters and return types
- Perform type-checking and type-inference such that return-types and
parameter types must always match.
- Do simple logic-operations (e.g. If/And/Or)
2025-07-26 14:37:49 +02:00
- Handle, access, define and initialize structs and arrays.
- Define and execute For/While loops
- Output detailed debug information
- Define extern functions that can be linked to outside modules such as `libc`.
- Define custom binary operations for any two types that hasn't been defined
previously (such as `u16 + u32`).
2025-07-09 19:27:12 +02:00
An example program of Reid, that calculates the 5th fibonacci number (and uses
Rust for highlighting) is:
```rust
fn main() -> u16 {
return fibonacci(5);
}
fn fibonacci(n: u16) -> u16 {
if n <= 2 {
return 1;
}
return fibonacci(n-1) + fibonacci(n-2);
}
```
2025-07-21 11:21:09 +02:00
Currently missing big features (TODOs) are:
2025-07-14 01:28:01 +02:00
- ~~Arrays~~ (DONE)
2025-07-17 11:37:57 +02:00
- ~~Structs~~ (DONE)
2025-07-14 21:57:33 +02:00
- ~~Extern functions~~ (DONE)
2025-07-14 16:57:34 +02:00
- ~~Strings~~ (DONE)
2025-07-21 08:57:18 +02:00
- ~~Borrows~~ (DONE)
- ~~Pointers~~ (DONE)
- ~~Unary operators~~
2025-07-21 16:32:41 +02:00
- ~~Floats~~ (DONE)
2025-07-22 22:01:55 +02:00
- ~~Type casting~~ (DONE)
2025-07-23 20:08:50 +02:00
- ~~Built-in Int/Float division and modulo~~ (DONE)
- ~~Loops~~ (DONE)
2025-07-24 19:25:25 +02:00
- ~~Intrinsic functions~~ (DONE)
- ~~Ability to specify types in literals and variable definitions~~ (DONE)
2025-07-25 02:05:16 +02:00
- ~~Debug Information~~ (DONE)
2025-07-27 01:19:45 +02:00
- ~~Fix struct initialization (wrong order and missing fields allowed now)~~ (DONE)
- ~~Not-Unary~~ (DONE)
- ~~Importing types from other modules~~ (DONE)
- ~~Importable binops?~~ (DONE)
2025-07-27 19:06:11 +02:00
- ~~Associated functions (for e.g. sizeof)~~ (DONE)
2025-07-21 11:21:09 +02:00
Big features that I want later but are not necessary:
2025-07-24 19:25:25 +02:00
- ~~User-defined binary operations~~ (DONE)
- ~~Asymmetric binary operations (e.g. string + u32)~~ (DONE)
2025-08-01 22:59:05 +02:00
- ~~Error handling~~ (Not Doing It)
- ~~Lexing & parsing of whitespace and comments as well~~ (DONE)
2025-08-03 23:21:10 +02:00
- ~~LSP implementation~~ (DONE)
- ~~Syntax Highlighting~~ (DONE)
- ~~Semantic Highlighting~~ (DONE)
- ~~Go-To-Definition~~ (DONE)
- ~~Find-All-References~~ (DONE)
- ~~Refactoring~~ (DONE)
2025-07-09 19:27:12 +02:00
Smaller features:
2025-07-29 15:04:26 +02:00
- ~~Hex-numbers~~ (DONE)
- ~~Bitwise operations~~ (DONE)
- ~~Easier way to initialize arrays with a single value~~ (DONE)
- ~~Void-returns (`return;` for void-returning functions)~~ (DONE)
- ~~Only include standard library at all if it is imported~~ (DONE)
- ~~Lexical scopes for Debug Information~~ (DONE)
2025-07-09 19:27:12 +02:00
### Why "Reid"
[ᚱ is an Elder Futhark rune](https://en.wikipedia.org/wiki/Raido) which means
"ride" or **"journey"**. As this language is meant for me to primarily learn
language design and compiler development, it is more about the *journey* rather
than the destination. ᚱ is written as "Reið" in Icelandic, which is the
inspiration behind "Reid" here.
### Why "Reid-LLVM"?
Because I have another project also called Reid, which only compiles to a
Virtual Instruction Set Architecture (V-ISA) that is executed via a custom-made
Virtual Machine. It is still hosted
[here](https://git.teascade.net/teascade/reid), but do note that it is very old
and not as representative of my skills as a programmer today as this one.
2025-07-05 00:52:03 +02:00
## What is currently being tested?
2025-07-24 22:07:40 +02:00
Currently when testing the compiler I run `./libtest.sh examples/{file}.reid`,
where the `{file}` is one of the various examples I've written to help me test
features of the compiler.
2025-07-05 00:52:03 +02:00
What `./libtest.sh $1` does, is it compiles and runs the rust example found at
2025-07-24 22:07:40 +02:00
path `$1`. Some pre-existing examples can be found in [`examples`](./examples)
2025-07-05 00:52:03 +02:00
All examples currently end up producing a `hello.o` and `hello.asm` file to the
root directory, which is then linked with `ldd` to produce a `main`, which is
finally executed.
This is currently very work-in-progress and many things about this repository
change erratically.
## Various notes in order to get this working properly
This is what worked for me, might not (probably) work for you, depending on
various versions of various libraries.
2025-07-18 22:03:53 +02:00
### Compiling LLVM 20.1.8
#### Context
Context for my computer. I am on ArchLinux, and here are some libraries and
their current versions that I have installed as of compiling, I'm not sure what
of them are relevant, if any, but saving them here still feels like a good idea
for the future:
2025-07-18 22:03:53 +02:00
- `clang 19.1.7-2`
- `cmake 4.0.2-1`
- `extra-cmake-modules 6.14.0-1`
- `gcc 15.1.1+r7+gf36ec88aa85a-1`
- `gcc-libs 15.1.1+r7+gf36ec88aa85a-1`
- `lib32-gcc-libs 15.1.1+r7+gf36ec88aa85a-1`
- `lib32-llvm-libs 1:19.1.7-2`
- `libgccjit 15.1.1+r7+gf36ec88aa85a-1`
- `lld 19.1.7-1`
- `lldb 19.1.7-2`
- `llvm 19.1.7-2`
- `llvm-libs 19.1.7-2`
- `llvm14 14.0.6-5`
- `llvm14-libs 14.0.6-5`
- `llvm15 15.0.7-3`
- `llvm15-libs 15.0.7-3`
- `make 4.4.1-2`
2025-07-18 22:03:53 +02:00
#### Commands
```sh
2025-07-18 22:03:53 +02:00
git clone https://github.com/llvm/llvm-project.git --depth=1 --branch=llvmorg-20.1.8
2025-07-18 22:03:53 +02:00
cd llvm_project
cmake llvm -B build -DCMAKE_BUILD_TYPE=MinSizeRel -DLLVM_ENABLE_ASSERTIONS=ON -DLLVM_INCLUDE_TESTS=OFF -DLLVM_BUILD_BENCHMARKS=OFF -G Ninja -DLLVM_USE_LINKER="ld.lld" -DLLVM_PARALLEL_LINK_JOBS=8
ninja -j23
```
### Building this crate itself
2025-07-18 22:03:53 +02:00
Assuming `llvm-project` from the previous step was at
`/path/llvm-project`, building this crate can be done via the following command:
```sh
2025-07-18 22:03:53 +02:00
LLVM_SYS_201_PREFIX=/path/llvm-project/build cargo build
```
2025-07-29 15:08:54 +02:00
Alternatively assuming you have LLVM 20.1 or newer installed you may use omit
the environment variable entirely and use dynamic linking instead