Repository for the book "Crafting Interpreters"

Overview

This is the repo used for the in-progress book "Crafting Interpreters". It contains the Markdown text of the book, full implementations of both interpreters, as well as the build system to weave the two together into the final site.

If you find an error or have a suggestion, please do file an issue here. Thank you!

Contributing

One of the absolute best things about writing a book online and putting it out there before it's done is that people like you have been kind enough to give me feedback, point out typos, and find other errors or unclear text.

If you'd like to do that, great! You can just file bugs here on the repo, or send a pull request if you're so inclined. If you want to send a pull request, but don't want to get the build system set up to regenerate the HTML too, don't worry about it. I'll do that when I pull it in.

Ports and implementations

Another way to get involved is by sharing your own implementation of Lox. Ports to other languages are particularly useful since not every reader likes Java and C. Feel free to add your Lox port or implementation to the wiki:

Building Stuff

I am a terribly forgetful, error-prone mammal, so I automated as much as I could.

Prerequisites

I develop on an OS X machine, but any POSIX system should work too. With a little extra effort, you should be able to get this working on Windows as well, though I can't help you out much.

Most of the work is orchestrated by make. The build scripts, test runner, and other utilities are all written in Dart. Instructions to install Dart are here. Once you have Dart installed and on your path, run:

$ make get

This downloads all of the packages used by the build and test scripts.

In order to compile the two interpreters, you also need a C compiler on your path as well as javac.

Building

Once you've got that setup, try:

$ make

If everything is working, that will generate the site for the book as well as compiling the two interpreters clox and jlox. You can run either interpreter right from the root of the repo:

$ ./clox
$ ./jlox

Hacking on the book

The Markdown and snippets of source code are woven together into the final HTML using a hand-written static site generator that started out as a single tiny Python script for my first book and somehow grew into something approximating a real program.

The generated HTML is committed in the repo under site/. It is built from a combination of Markdown for prose, which lives in book/, and snippets of code that are weaved in from the Java and C implementations in java/ and c/. (All of those funny looking comments in the source code are how it knows which snippet goes where.)

The script that does all the magic is tool/bin/build.dart. You can run that directly, or run:

$ make book

That generates the entire site in one batch. If you are incrementally working on it, you'll want to run the development server:

$ make serve

This runs a little HTTP server on localhost rooted at the site/ directory. Any time you request a page, it regenerates any files whose sources have been changed, including Markdown files, interpreter source files, templates, and assets. Just let that keep running, edit files locally, and refresh your browser to see the changes.

Building the interpreters

You can build each interpreter like so:

$ make clox
$ make jlox

This builds the final version of each interpreter as it appears at the end of its part in the book.

You can also see what the interpreters look like at the end of each chapter. (I use this to make sure they are working even in the middle of the book.) This is driven by a script, tool/bin/split_chapters.dart that uses the same comment markers for the code snippets to determine which chunks of code are present in each chapter. It takes only the snippets that have been seen by the end of each chapter and produces a new copy of the source in gen/, one directory for each chapter's code. (These are also an easier way to view the source code since they have all of the distracting marker comments stripped out.)

Then, each of those can be built separately. Run:

$ make c_chapters

And in the build/ directory, you'll get an executable for each chapter, like chap14_chunks, etc. Likewise:

$ make java_chapters

This compiles the Java code to classfiles in build/gen/ in a subdirectory for each chapter.

Testing

I have a full Lox test suite that I use to ensure the interpreters in the book do what they're supposed to do. The test cases live in test/. The Dart program tool/bin/test.dart is a test runner that runs each of those test files on a Lox interpreter, parses the result, and validates that that the test does what it's expected to do.

There are various interpreters you can run the tests against:

$ make test       # The final versions of clox and jlox.
$ make test_clox  # The final version of clox.
$ make test_jlox  # The final version of jlox.
$ make test_c     # Every chapter's version of clox.
$ make test_java  # Every chapter's version of jlox.
$ make test_all   # All of the above.

Testing your implementation

You are welcome to use the test suite and the test runner to test your own Lox implementation. The test runner is at tool/bin/test.dart and can be given a custom interpreter executable to run using --interpreter. For example, if you had an interpreter executable at my_code/boblox, you could test it like:

$ dart tool/bin/test.dart clox --interpreter my_code/boblox

You still need to tell it which suite of tests to run because that determines the test expectations. If your interpreter should behave like jlox, use "jlox" as the suite name. If it behaves like clox, use "clox". If your interpreter is only complete up to the end of one of the chapters in the book, you can use that chapter as the suite, like "chap10_functions". See the Makefile for the names of all of the chapters.

If your interpreter needs other command line arguments passed to use, pass them to the test runner using --arguments and it will forward to your interpreter.

Repository Layout

  • asset/ – Sass files and jinja2 templates used to generate the site.
  • book/ - Markdown files for the text of each chapter.
  • build/ - Intermediate files and other build output (except for the site itself) go here. Not committed to Git.
  • c/ – Source code of clox, the interpreter written in C. Also contains an XCode project, if that's your thing.
  • gen/ – Java source files generated by GenerateAst.java go here. Not committed.
  • java/ – Source code of jlox, the interpreter written in Java.
  • note/ – Various research, notes, TODOs, and other miscellanea.
  • note/answers – Sample answers for the challenges. No cheating!
  • site/ – The final generated site. The contents of this directory directly mirror craftinginterpreters.com. Most content here is generated by build.py, but fonts, images, and JS only live here. Everything is committed, even the generated content.
  • test/ – Test cases for the Lox implementations.
  • tool/ – Dart package containing the build, test, and other scripts.
Issues
  • Any hints implementing break and continue?

    Any hints implementing break and continue?

    I had trouble implementing break statement. I already added the tokens and statements with zero parameters (maybe there should be some - probably some context). I don't know how you would check if break is within a loop. I thought maybe check the tokens, but that would be tedious. Also I don't know how you would break out of a loop which is visited as another statement. Thought about exceptions but I know that is not the right way. So maybe you can give me some hints for these. Maybe it would be useful to put them in a book too because currently a note in challenge only describes what break is.

    opened by fsacer 11
  • Marginal Collisions in the Typesetting

    Marginal Collisions in the Typesetting

    In some layouts, the "margin grafiti" (as Knuth would call it) and the source file annotations overlap.

    See the attached screenshot, where main.c\n add to top of file overlaps with "The code tests for one and two arguments, ..." in the margins on the right-hand-side.

    layout-nightmare

    opened by pqnelson 10
  • Typo: chapter 2.3

    Typo: chapter 2.3

    This line in chapter 2.3 may need adjustment:

    So go has a compiler, is an interpreter, and is also a compiler.

    Also, I am by no means an expert on this field (that's why I am reading the book!), but is go really an interpreter, or is it the OS/CPU which actually interprets the go generated executable. Whereby the command, go run acts as a wrapper to compile, then start the interpretation which is done by the OS/CPU?

    Anyway, thanks again for another great book!

    opened by scottwillmoore 8
  • Invalid section of code?

    Invalid section of code?

    @munificent Section https://www.craftinginterpreters.com/statements-and-state.html#assignment-syntax shows this block of code:

      private Expr assignment() {
        Expr expr = equality();
    
        if (match(EQUAL)) {
          Token equals = previous();
          Expr value = assignment();
    
          if (expr instanceof Expr.Variable) {
            Token name = ((Expr.Variable)expr).name;
            return new Expr.Assign(name, value);
          }
    
          error(equals, "Invalid assignment target."); 
        }
    
        return expr;
      }
    

    However, my IDE warns that the "Result of 'error()' is not thrown", so I think it should say:

          . . .
          throw error(equals, "Invalid assignment target."); 
          . . .
    

    What do you think?

    P.S. This book is excellent! I'm enjoying reading it so far and it's shed a lot of light for me on how compilers and tools like ANTLR work. I wish you all the best with writing the rest.

    opened by jbduncan 7
  • Typo in Chapter 3: The Lox Language - Closures snippet?

    Typo in Chapter 3: The Lox Language - Closures snippet?

    Section 3.8.1, Closures, includes this code snippet to demonstrate passing around a function as an argument:

    print identity(addPair)(1, 2); // Prints "3".

    Can that be right? Aren't the parentheses misplaced? Shouldn't this be:

    print identity(addPair(1, 2)); // Prints "3".

    opened by bhagerty 7
  • Chapter 1: Challenges,  #3, seriously?

    Chapter 1: Challenges, #3, seriously?

    I open up a hoopyfroop book and read the introductory chapter. It says, "hey, we're going to make a couple languages in Java, and later, we will learn about the structures to do it in C. No problem; we'll take it slow". Then I get to the challenges, #1 is a 'look at the repo and notice all the little languages', #2 is 'go get a Java Environment set up, you can figure that out.', and then we get #3: 'oh, also set up a C environment because we might need that if you stay with the book for a dozen chapters, and you should write some link lists in it, with helper functions, and tests.'

    Are you sure it's not a typo and should say: "3. As a challenge, implement your own version of Linux in C. "

    opened by merriam 7
  • Remove Expr.Grouping

    Remove Expr.Grouping

    Parenthesis are here to allow a user to specify how to parse something, once the grammar is parsed, there is no need for an AST node that represent the fact that the input file has to be parsed in a certain way.

    So Expr.Grouping and the corresponding visits that does nothing can be removed.

    opened by forax 7
  • Missing information about status.

    Missing information about status.

    The document is copyright 2015 but only has the first 4 chapters. The rest say "coming soon!" but that's obviously not true. Please do your readers a favor and include information about the actual status and progress of this book and when they can realistically expect to see the rest of it. As it is, reading this is a waste of time when so much of the document is missing. Also it's a waste of time to post issues about the content, which I had intended to do.

    opened by jibal 7
  • Module system in Lox

    Module system in Lox

    Thank you for your amazing book :D

    I have currently learned to write my interpreter following the book. But I don't know how to implement a module system like Python. I couldn't find any tutorials on the internet.

    I appreciate it if you give me a couple of hints.

    discussion 
    opened by bichanna 6
  • Expression result not printed after execution

    Expression result not printed after execution

    In Repl mode, It's always better to be interactive and show how easy and fun using a programming language can be. After trying current version of Lox, figured out you need to use print statement to figure out what is the result of an expression.

    By expression I mean return value of function, Initial expression of variable and direct coding like 1 / 2 .

    Issue current-version :

    10 + 10 ; ..

    opened by mhmdvoid 6
  • Private class methods

    Private class methods

    I was wondering how one can implement or if anyone has successfully implemented private methods in Lox. Has anyone done this?? Is there a reference?? Any help appreciated.

    discussion 
    opened by mcfriend99 6
  • Update README.md

    Update README.md

    The very first sentence of https://github.com/munificent/craftinginterpreters/blob/master/README.md reads as follows:

    This is the repo used for the in-progress book "Crafting Interpreters".

    Since the book has now been published, we can no longer describe it as being "in-progress".

    Please update the README.md appropriately.

    opened by cm1776 0
  • Ch18 - peek() function needs forward declaration

    Ch18 - peek() function needs forward declaration

    In Ch18, the book tells me to add the static Value peek(int distance) function "after pop()" in vm.c. Of course, peek() is called earlier in that file, so it won't compile without a forward declaration. I added one and things compile and run just fine, but it seemed odd that the book text didn't mention it (unless I missed it somehow).

    opened by Sidewinder1138 1
  • Question Regarding 8.2.1

    Question Regarding 8.2.1

    In 8.2.1, you state that the following is illegal:

    if (monday) var beverage = "espresso";

    With the following afterwards:

    We could allow the latter, but it’s confusing. What is the scope of that beverage variable? Does it persist after the if statement? If so, what is its value on days other than Monday? Does the variable exist at all on those days?

    Code like this is weird, so C, Java, and friends all disallow it.

    Actually, I don't find this confusing or weird at all, and now that I think about it, I find this exception to be both confusing and weird. The purist in me has a serious problem with it. Why disallow it? I admit that it serves no purpose, but I can create many legal statements that serve no purpose.

    You made this illegal: if (monday) var beverage = "espresso";

    But this isn't?

    if (monday) {
        var beverage = "espresso";
    }
    

    You (and those who came before you) are treating a statement block differently than a statement. And for no good reason, really.

    The answers to all of your questions about the first example are simple, because they're exactly the same as they would be in the second example:

    What is the scope of the beverage variable?

    The scope is the statement executed when monday is true. Exactly as it would be in the second example.

    Does it persist after the if statement?

    No, of course not. The question itself is ludicrous. Would it persist outside of the statement block in the second example?

    If so, what is the value on days other than Mondays? Does the variable exist at all on those days?

    Again, the questions themselves are ludicrous. Of course the variable doesn't exist on days other than Mondays. You wouldn't expect it to in the second example. Why would you have any questions at all about the first?

    Were I designing Lox, this would be a perfectly legal, if admittedly, completely useless statement.

    I think that if you're going to disallow it, you have to justify it better. I don't find your justification convincing at all.

    opened by chrisjbreisch 0
  • Fix GC paper link

    Fix GC paper link

    Hi, thanks for this amazing work.

    While reading I noticed this broken link to a GC paper.

    I don't know if using web archive is the optimal solution, but I decided to open a PR to let you know.

    opened by shyba 0
  • Design discussion Print statement

    Design discussion Print statement

    Hi, just wondering if you were aware of this (probably you are), but just wanted to point out a possible idea:

    var a = 1;
    print(a);
    1
    print(a=123);
    123
    print(a);
    123
    

    I basically think that passing a Boolean for the Expression statement can solve this issue, that way you know if the expression can be used for assignments or not.

    opened by badc0re 3
Owner
Bob Nystrom
Programming language developer, ex-game developer, UI nerd, author of "Game Programming Patterns" and "Crafting Interpreters".
Bob Nystrom
A place to collaborate on code for the Embedded.fm book club. Currently reading "STM32 ARM Programming for Embedded Systems".

Welcome to the Book Club Code site! This is a place for the Embedded.fm book club to collaborate and learn together. Repo Structure Guide Top-level fo

Peter Griffin 10 Jan 13, 2022
C++ Premier plus 6th edition book solved exercise.

c-premier-plus-6th-edition-solved-exercise C++ Premier plus 6th edition book exercise solutions. These exercise solved by me when i learning c++, so d

Zaid Rao 1 Oct 31, 2021
Source code for the "C Unleashed" book by Richard Heathfield, Lawrence Kirby, et al.

Source code from the book "C Unleashed" "C Unleashed" was written by Richard Heathfield, Lawrence Kirby and several other collaborators and published

Eli Bendersky 47 Jun 9, 2022
Resolução de exercícios do e-book 300 ideias para programar

Repositório 300 ideias para programar Saudações! Este repositório é dedicado a resolução dos exercícios do e-book 300 IDÉIAS PARA PROGRAMAR COMPUTADOR

Code Brasil 2 Jan 1, 2022
Software to support people learning OpenMP with our book

Software to support people learning OpenMP with our book ... The OpenMP Common Core: Making OpenMP Simple Again

Tim Mattson 41 Jun 10, 2022
This repository is for everyone for Hacktoberfest 2021. Anyone can contribute anything for your Swags (T- Shirt), must be relevant that can add some value to this repository.

Hacktober Fest 2021 For Everyone! Upload Projects or Different Types of Programs in any Language Use this project to make your first contribution to a

Mahesh Jain 16 Dec 21, 2021
This Repository is created to help fellow coders learn open source contributions. This Repository is created for Hacktoberfest 2021

Hacktoberfest 2021 Follow the README below to get started! This Repository is created to help fellow coders learn open source contributions This Repos

Somesh Debnath 7 Apr 26, 2022
This repository is a study repository to implement the LCD 16x2 in my project below

This repository is a study repository to implement the LCD 16x2 in my project below. Index ?? About ?? Functionalities ?? Deploy ?? Requirements ?? Pi

Rickelme Dias 3 Jun 7, 2022
This repository is used for automatic calibration between high resolution LiDAR and camera in targetless scenes.

livox_camera_calib livox_camera_calib is a robust, high accuracy extrinsic calibration tool between high resolution LiDAR (e.g. Livox) and camera in t

HKU-Mars-Lab 377 Jun 30, 2022
Learn how to connect your Flexispot (LoctekMotion) desk to the internet. This repository contains a collection of scripts to get your started, combined with research and instructions.

(image source: Windows Central) Turn your LoctekMotion/FlexiSpot desk into a smart desk Recently I acquired a new standing desk from FlexiSpot. During

Mick Vleeshouwer 147 Jun 21, 2022
This repository contains toy ImPlot applications that demonstrate some of the library's functionality

ImPlot Demos This repository contains toy ImPlot applications that demonstrate some of the library's functionality.

Evan Pezent 58 Jun 26, 2022
This repository is to explain how the SN74HC595 register works

Register_SN74HC595 This repository is to explain how the SN74HC595 register works Aujourd’hui on va apprendre à comment augmenter le nombre de sortie

mugiwarra229 5 Jun 8, 2021
Southwest University Lanqiao Cup Training Repository, April 2021

2021 Southwest University Lanqiao Cup Trainning Course Summary This repository is using for LanqiaoCup Competition on 18th, April, 2021 How to start W

西南大学ACM实验室 9 Apr 15, 2021
Officially repository Competitive Programming ID

Competitive Programming ID Official repository of Competitive Programming ID (https://t.me/CP_ID) Codewars Stats -------------------------------------

DVL ナンダ 17 May 9, 2022
This repository is to share the EdgeAI Lab with Microcontrollers Series material to the entire community

This repository is to share the EdgeAI Lab with Microcontrollers Series material to the entire community. We will share documents, presentations and source code of two demo applications.

Machine Learning Tokyo 15 Oct 23, 2021
the first ever open source zombie killcam mod for bo2 zombies. this repository is the original mod.

BO2 T6ZM Killcams (+ Mod Menu) my zombie killcam mod that is a work-in-progress and open sourced. this may work off plutonium but this was only suppor

m 4 Jun 6, 2022
Repository created to store a C function library to use in 42 School

Libft of 42. Make with ❤︎ for Luiz Cezario ?? Index What's this Repo? List of Functions Technologies How to Run Find a Bug? Or somenthing need to chan

Luiz lima cezario 8 Feb 20, 2022
This repository provides you the material of installation the Catalana Hackintosh

VivoBook Asus X542UQ laptop Catalina 10.15.7 Hackintosh This repository provides you the material of installation the Catalana Hackintosh with Opencor

Vlad Tatarinov 2 Oct 9, 2021
A repository for Dsa solutions and approaches 📚📕

Coffee and Code ?? Coffee and Code is a Question Bank that provides solving patterns and resources along with solutions in diffrent language to help y

null 16 Nov 28, 2021