llforth
llforth copied to clipboard
Experimental implementation of Forth in LLVM
LLForth 
Experimental Forth implementation in LLVM.
Introduction blog post is here: https://medium.com/@riywo/llforth-experimental-implementation-of-forth-in-llvm-2298c76ec3ac
Summary
This software is built for a personal research to understand computer architecture. Implementing stack-based programming language(Forth) using a register-based virtual machine (LLVM) is useful to know both machine/language architecture.
LLForth uses following technique:
- Restricted static compiler (
llforthc) from Forth to LLVM Intermediate Representation (LLVM IR) and Full feature interpreter (llforth) written in Forth and compiled byllforthc - Indirect Threaded Code (ITC) to implement inner interpreter by LLVM IR
- Naive memory implementation for Stack and Return Stack by LLVM IR
- Partial memory cell for only word definitions excluding string of name of words
- Foreign Function Interface to delegate platform dependent features (e.g. stdio) to Rust and share it between compiler and interpreter
Getting started
Prerequisites (versions are tested by the author)
- CMake (3.13.2)
- LLVM (7.0.0)
- lit (from PyPI or under LLVM source code)
- Rust (1.31.1)
Build
All required steps are declared in CMakeLists.txt including compiling Rust library, so you just need to execute CMake build:
$ mkdir cmake-build-debug
$ cd cmake-build-debug
# If you install LLVM outside default path like Homebrew:
# export LLVM_DIR=/usr/local/opt/llvm/lib/cmake
$ cmake ..
$ make llforth
Execution
llforth is statically linked with required libraries except libc:
$ otool -L ./llforth
./llforth:
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1252.200.5)
Therefore, you can execute it easily:
$ ./llforth --help
llforth 0.1
USAGE:
llforth [FILE]
FLAGS:
-h, --help Prints help information
-V, --version Prints version information
ARGS:
<FILE> Source file
Usage
llforth can read from both stdin and source file. For example, you can run it interectively powered by Rustyline which is Readline like library:
$ ./llforth
> 1 1 + .
2
> : hi ." Hello world!" ;
> hi
Hello world!
Also, you can input via stdin non-interectively:
$ echo '1 2 + .' | ./llforth
3
Finally, you can read a source file on your file system:
$ echo '1 2 + .' > /tmp/test.fs && ./llforth /tmp/test.fs
3
Supported words
See https://github.com/riywo/llforth/wiki/Supported-words
Architecture
See https://github.com/riywo/llforth/wiki/Architecture
Acknowledgments
Low-Level Programming / Forthress
This project is heavily inspired from a book "Low-Level Programming" which has a great section for implementing Forth using x86_64 assembly only. The code base is also available from the author's repository called Forthress under MIT License. Most of architectures of LLForth are borrowed from Forthless, for example ITC, Memory cell, etc.
Series of posts on the evolution of TransForth
On top of the assembly implementation mirrored from Forthress, I implemented some forth words by forth, for example if ... else ... then or begin ... until. Those words are borrowed from "Series of posts on the evolution of TransForth" which are awesome read to understand Forth architecture. The code base is also available on TransForth under MIT License.