/nim-nlox

nlox is a Nim implementation of the Lox programming language interpreter

Primary LanguageNimMIT LicenseMIT

nlox is a Nim implementation of the Lox programming language interpreter. This implementation is based on the jlox interpreter, which is done in Java.

What is Lox?

Lox is a scripting language created by Robert Nystrom to teach in a practical way the implementation of a programming language throughout the book Crafting Interpreters. To learn more, visit craftinginterpreters.com.

Why write another Lox interpreter?

I have always been interested in learning how a programming language is implemented and the book Crafting Interpreters brings this in a very didactic and practical way. So it's a perfect opportunity to learn something new and develop myself as a programmer.

Why use the Nim programming language?

Nim is currently the programming language I have the best aptitude for and I feel more comfortable exploring something new and unknown. I tried to keep this Nim implementation as faithful as possible with the base implementation made in Java.

Challenges when using Nim

Certainly the biggest challenge during codification was avoiding cyclical imports that are prohibited in Nim, which emerged as chapter by chapter progressed. To achieve this, some refactorings were necessary, which meant that some codes were left out of comparable files in the Java implementation, such as types, which I had to include for the most part in src/nlox/types.nim, which is a very popular practice in Nim.

The second biggest problem was trying to emulate the Java equals() method, which underwent some changes throughout the chapters and I still believe there is something missing...

Another part that underwent a lot of refactoring were the literals, such as Number, String, Boolean and Nil. At first I adopted variants objects of Nim , but with the arrival of expression evaluations, this approach proved to be a mistake, making it necessary to switch to objects with inheritance. It was a painful but necessary refactoring.

Finally, from the beginning I knew that I would need to pass a state from the interpreter, but I didn't want to do that with globals. To this end, I first adopted global ones, so that when the interpreter had become more consolidated, I created a Lox object to store the state of the interpreter and pass it wherever necessary.

Progress

I. WELCOME

  • 1. Introduction
  • 2. A Map of the Territory
  • 3. The Lox Language

II. A TREE-WALK INTERPRETER

  • 4. Scanning
  • 5. Representing Code
  • 6. Parsing Expressions
  • 7. Evaluating Expressions
  • 8. Statements and State
  • 9. Control Flow
  • 10. Functions
  • 11. Resolving and Binding
  • 12. Classes
  • 13. Inheritance

Visit nloxvm to see the Nim implementation of the clox-based Lox VM interpreter.

How to use nlox?

First you need to have a Nim 2.0.0 compiler or higher.

Then clone this repository:

git clone https://github.com/rockcavera/nim-nlox.git

Enter the cloned folder:

cd nim-nlox

Finally, compile the project:

nim c -d:release src/nlox

or install with Nimble:

nimble install

For best performance, I recommend compiling with:

nim c -d:danger -d:lto --mm:arc --panics:on src/nlox

How to perform tests?

Assuming you have already cloned the repository, just be in the project folder and type:

nim r tests/tall

or:

nimble test

nlox vs jlox benchmark

visit BENCHMARK.md

License

All files are under the MIT license, with the exception of the .lox files located in the tests/scripts folder, which are under this LICENSE because they are third-party code, which can be accessed here.