Writing Interpreters in Rust: a Guide

Overview

Writing Interpreters in Rust: a Guide

This is an online book covering the lower level topics involved in writing an interpreter in Rust including:

  • memory management: allocation and garbage collection
  • compiling: expressions, functions, closures
  • virtual machines: bytecode, instruction dispatch

Project vision

From CPython to Ruby's YARV, V8 and SpiderMonkey, GHC to the JVM, most language runtimes are written in C/C++.

We believe that Rust is eminently suitable for implementing languages and can provide significant productivity improvements over C and C++ while retaining the performance advantages and low level control of both.

While there are a number of languages implemented in Rust available now, in varying states of completeness - interpreters, AOT compilers and JIT-compiled - our vision is singular:

To create a well documented reference compiler and runtime, permissively licensed, such that you can fork and morph it into your own programming language.

That is, a platform for bootstrapping other languages, written in Rust. To that end, the implementation provided here is not intended to be feature complete and cannot possibly represent every variation of programming language or local optimization.

It is a lofty goal, and it certainly won't be the right approach for everybody. However, we hope it will help shift the landscape in favor of more memory-safe language implementations.

Getting involved

See CONTRIBUTING.md for licensing and how to get involved.

The contents

The rendered book can be read here while the accompanying source code can be browsed in this repository.

Comments
  • Obtaining blocks of memory

    Obtaining blocks of memory

    There are options in Rust, depending on circumstances and requirements:

    Nightly only:

    • use of experimental alloc features on nightly Rust
      • access the global allocator https://doc.rust-lang.org/nightly/alloc/alloc/struct.Global.html
      • allows specifying block alignment
      • cross-platform

    Stable:

    • libc::posix_memalign() (and equivalent on other platforms that I'm not familiar with)
      • https://github.com/jonas-schievink/aligned_alloc.rs
      • allows specifying block alignment
      • platform-specific solutions
    • using a Vec as a *mut u8
      • https://github.com/reem/rust-memalloc
      • no way to specify block alignment
    opened by pliniker 8
  • Tagged Pointer: Nil == 0?

    Tagged Pointer: Nil == 0?

    First of all, great work on the book, I've been really enjoying reading through it!

    I noticed that the implementation of TaggedPtr represents nil as a pointer with a tag of 0. I've also noticed that integers are represented with a tag of 0.

    Would this not make a literal 0 be equal to nil, and mean that a zero integer would always be converted to a nil FatPtr (due to this code here )? Not sure if this is an intentional part of the design or not :)

    opened by andybest 4
  • Bump Allocation

    Bump Allocation

    We need a chapter on allocating memory. I'm specifically thinking of bump allocation because:

    1. It's super easy to implement
    2. It delivers good performance
    3. It can support concurrent and atomic operations, though you may still need locking in certain cases (e.g. when requesting a new arena to allocate into)
    opened by YorickPeterse 3
  • "Writing Interpreters in Rust: a Guide" WIP draft

    Book rendering updated on each push: https://pliniker.github.io/book/

    What this is:

    • a work in progress draft of an online book "Writing Interpreters in Rust: a Guide"
    • accompanying source code for an allocator and an interpreter (compiler and virtual machine)
    • lots of rough edges:
      • compiler warnings (mostly function X is never called)
      • missing features (mostly language completeness and garbage collection itself)
      • TODOs in the source code
      • likely lots of unidiomatic Rust (I stopped trying to keep up with what is idiomatic and focused on getting something done)
      • very likely a few soundness bugs
      • lots of unoptimized code
      • under-documented code
      • probably some wheel-reinventing that crates out there already solved
      • book is in progress

    This is obviously an absurdly large pull request. The history of that is that in the early days there was a lot of churn in my code design (implying a long period where I lacked confidence in my choices) and so by the time the architecture had stabilized there was already quite a lot of code.

    Proceeding

    My intention is to focus on the book until it is caught up with the source code.

    PRs and contributions

    If this looks at all interesting to anybody, some questions should be discussed:

    1. book license
      • I think this should be some form of Creative Commons but which one?
    2. source code license
      • I initially picked MPLv2 because I have some sympathy to copyleft
      • I also recognize that this is a rare choice and there are arguments in favor of more copyleft but possibly even more arguments toward the commonly used MIT/Apache2 in the Rust community. MPLv2 is a middle-way IMO but :man_shrugging:
    3. This PR is too big to be sanely reviewed. Options:
      • just accept it, ugly parts and all as something to start from: merge it to base/master and create issues and PRs from there on
      • don't accept it as is, fork this fork and make PRs to it until it's acceptable quality. This could take a long time.

    What should this become?

    What should the book and code cover, going forward?

    • priorites: some roadmap https://github.com/rust-hosted-langs/book/issues
    • consider: language and architectural design ideas https://github.com/rust-hosted-langs/runtimes-WG/issues

    What I'd like this to be is a repository that somebody can fork and design their own language from, where the builiding blocks are provided. A language design kit, almost. That's a way off though.

    opened by pliniker 1
  • Add Travis script to build+serve book from master

    Add Travis script to build+serve book from master

    See https://github.com/crate-ci/cargo-ghp-upload for more about the ghp-upload tool.

    Build will end up at https://rust-hosted-langs.github.io/book/master/.

    This requires Travis to have write-access to your repository. The simplest (and reasonably secure) way to achieve this is to create a Persional API Access Token with public_repoo scope. Then on Travis, define the secure environment variable GH_TOKEN with the value being the new token.

    If you want to provide more scoped access, you can use a deploy key for repo-specific access. If no token is provided, the script will use SSH to clone from and write to the repository. Travis Pro handles the deploy key automatically, and free users can use Travis encrypt-file plus a script to move the private key into the correct location.

    This also means that cargo ghp-upload works locally so long as you have ssh set up for your account. Branch and origin context are collected from Git instead of the CI environment. This means that cargo ghp-upload will work on CI other than Travis, but you currently have to manually prevent it from running on PR builds if you don't wan't it to.

    opened by CAD97 1
  • Update introduction to explain level of experience expected

    Update introduction to explain level of experience expected

    Bob Nystrom's Crafting Interpreters does a great job of explaining concepts with diagrams. Maybe we can do similarly in this book but at this point I'd consider Bob's book as leading into this book.

    opened by pliniker 0
  • Obtaining blocks of memory

    Obtaining blocks of memory

    Included:

    • fully functional travis build of docs (thanks @CAD97 !)
    • most of #9 with Windows allocation yet to do
    • a short section on alignment
    • a short section on the type of allocation in Rust terms

    https://pliniker.github.io/book/master/index.html https://github.com/pliniker/book/blob/master/blockalloc/src/lib.rs

    opened by pliniker 0
  • Explain why a custom allocator is needed at start of the book

    Explain why a custom allocator is needed at start of the book

    Hi, thanks for the book It is very helpful.

    I don't get the rationale for having a custom allocator though, shouldn't it be explained at the start? Wouldn't default rust allocator be good for this?

    opened by ghost 2
  • Improve efficiency of fetching next opcode

    Improve efficiency of fetching next opcode

    See interpreter/src/bytecode.rs:293 - multiple dereferences required to fetch a single opcode.

    Ideal state: an instruction pointer that is a pointer to the next opcode.

    Realistically: that might not be sensible, given that we probably want to retain bounds checking; what about extending Array with a RefCell-style ArrayOpcode slice borrow? That's as close to bare pointer in safe Rust as we can get.

    Files:

    • interpreter/src/bytecode.rs:293
    • booksrc/chapter-interp-bytecode.md
    easy data structures 
    opened by pliniker 0
  • In implementation of Array, replace Cell<RawArray> with RefCell

    In implementation of Array, replace Cell with RefCell

    Originally, Array didn't have runtime-borrow capability and I made the (hasty) decision to base the Array struct on using Cell<RawArray<T>>.

    It is clear that it makes far more sense to use RefCell now, both from a semantic and performance basis. The explicit borrowflag can also be removed.

    Source: interpreter/src/array.rs:42 Book: booksrc/chapter-interp-arrays.md

    good first issue data structures 
    opened by pliniker 0
  • CellPtr and TaggedCellPtr can't be Copy because std::cell::Cell isn't copy

    CellPtr and TaggedCellPtr can't be Copy because std::cell::Cell isn't copy

    This seems wrong. Since these types are just storing word-sized pointers and the behavior we want is to be able to copy them optimally, there should be no other reason why they can't be Copy.

    There must be a crate out there that provides Cell mechanics while also being Copy, maybe we need to define our own.

    good first issue easy 
    opened by pliniker 0
Owner
Languages Hosted in Rust Working Groups
Working groups for exploring languages and runtimes hosted in the Rust programming language. (Not officially affiliated with Rust.)
Languages Hosted in Rust Working Groups
A Rust macro for writing nested loop expressions

loop_chain A Rust macro for writing nested loop expressions Usage | Examples | Docs Dependencies [dependencies] loop_chain = "0.1.1" Usage For express

Takayuki Maeda 5 Jul 30, 2021
Take your first step in writing a compiler. Implemented in Rust.

first-step-rust Take your first step in writing a compiler, using Rust. Building from Source Make sure the Rust toolchain is installed on your compute

PKU Compiler Course 13 Aug 28, 2022
S-expression parsing and writing in Rust

rsexp S-expression parsing and writing in Rust using nom parser combinators. This implemantion aims at being compatible with OCaml's sexplib. The main

Laurent Mazare 12 Oct 18, 2022
Learn Rust by writing Entirely Too Many linked lists

Learn Rust by writing Entirely Too Many Linked Lists Read the pretty version at https://rust-unofficial.github.io/too-many-lists/. Building Building r

null 2.4k Jan 3, 2023
This project contains small exercises to get you used to reading and writing Rust code

rustlings ?? ❤️ Greetings and welcome to rustlings. This project contains small exercises to get you used to reading and writing Rust code. This inclu

Cynthia Tran 1 May 24, 2022
🕶 Assorted checks and validations for writing safer Solana programs.

vipers ?? Assorted checks and validations for writing safer Solana programs. Motivation Solana's fee mechanism is unlike Ethereum's, in that the numbe

Saber 131 Sep 14, 2022
A webring of people who make cool stuff. technology, music, art, writing, anything goes!

a webring of people who make cool stuff. technology, music, art, writing, anything goes!

Kognise 44 Dec 6, 2022
A language for writing swim practices.

swimscript A language for writing swim practices. Table of contents Purpose Language Spec Purpose The goal of swimscript is to create a universal lang

Aiden Petersen 1 Jan 30, 2022
Thread-safe clone-on-write container for fast concurrent writing and reading.

sync_cow Thread-safe clone-on-write container for fast concurrent writing and reading. SyncCow is a container for concurrent writing and reading of da

null 40 Jan 16, 2023
Leetcode Solutions in Rust, Advent of Code Solutions in Rust and more

RUST GYM Rust Solutions Leetcode Solutions in Rust AdventOfCode Solutions in Rust This project demostrates how to create Data Structures and to implem

Larry Fantasy 635 Jan 3, 2023
Simple autoclicker written in Rust, to learn the Rust language.

RClicker is an autoclicker written in Rust, written to learn more about the Rust programming language. RClicker was was written by me to learn more ab

null 7 Nov 15, 2022
Rust programs written entirely in Rust

mustang Programs written entirely in Rust Mustang is a system for building programs built entirely in Rust, meaning they do not depend on any part of

Dan Gohman 561 Dec 26, 2022
Rust 核心库和标准库的源码级中文翻译,可作为 IDE 工具的智能提示 (Rust core library and standard library translation. can be used as IntelliSense for IDE tools)

Rust 标准库中文版 这是翻译 Rust 库 的地方, 相关源代码来自于 https://github.com/rust-lang/rust。 如果您不会说英语,那么拥有使用中文的文档至关重要,即使您会说英语,使用母语也仍然能让您感到愉快。Rust 标准库是高质量的,不管是新手还是老手,都可以从中

wtklbm 493 Jan 4, 2023
A library for extracting #[no_mangle] pub extern "C" functions (https://docs.rust-embedded.org/book/interoperability/rust-with-c.html#no_mangle)

A library for extracting #[no_mangle] pub extern "C" functions In order to expose a function with C binary interface for interoperability with other p

Dmitrii - Demenev 0 Feb 17, 2022
clone of grep cli written in Rust. From Chapter 12 of the Rust Programming Language book

minigrep is a clone of the grep cli in rust Minigrep will find a query string in a file. To test it out, clone the project and run cargo run body poem

Raunak Singh 1 Dec 14, 2021
Rust-blog - Educational blog posts for Rust beginners

pretzelhammer's Rust blog ?? I write educational content for Rust beginners and Rust advanced beginners. My posts are listed below in reverse chronolo

kirill 5.2k Jan 1, 2023
The ray tracer challenge in rust - Repository to follow my development of "The Raytracer Challenge" book by Jamis Buck in the language Rust

The Ray Tracer Challenge This repository contains all the code written, while step by implementing Ray Tracer, based on the book "The Ray Tracer Chall

Jakob Westhoff 54 Dec 25, 2022
Learn-rust-the-hard-way - "Learn C The Hard Way" by Zed Shaw Converted to Rust

Learn Rust The Hard Way This is an implementation of Zed Shaw's Learn X The Hard Way for the Rust Programming Language. Installing Rust TODO: Instruct

Ryan Levick 309 Dec 8, 2022
Learn to write Rust procedural macros [Rust Latam conference, Montevideo Uruguay, March 2019]

Rust Latam: procedural macros workshop This repo contains a selection of projects designed to learn to write Rust procedural macros — Rust code that g

David Tolnay 2.5k Dec 29, 2022