GitXplorerGitXplorer
h

slox

public
12 stars
1 forks
1 issues

Commits

List of commits on branch master.
Unverified
06d83be9b25f1e10571233a39ec7705e337f563f

Minor readme edit

hhashemi committed 7 years ago
Unverified
0546c64a54a8c8e82613eba8f79722cdc17cba08

Update readme with link to bslox

hhashemi committed 7 years ago
Unverified
5e9e3b6fd583bc911706520c140026d3ec6d5fd6

Add & modify benchmark.py from Bob’s repo

hhashemi committed 7 years ago
Unverified
bd26665875c1463ae2f71ac50aaafa099146a876

Refactor Environment from linked list to array

hhashemi committed 7 years ago
Unverified
f5bbfcb50008be838f74cb94dc61349382bf1ab3

Docouple Token from interpreted literal values

hhashemi committed 7 years ago
Unverified
d333f87a750942e1ec1e09399d770708aa648499

Fix usage of Character instead of UnicodeScalar

hhashemi committed 7 years ago

README

The README file for this repository.

slox

This is an interpreter of the Lox Language written in Swift.

This project follows Bob Nystrom's excellent book, Crafting Interpreters which takes you through the process of writing an interpreter for a language called Lox.

In the book, the lox is implemented as an tree-walking interpreter in Java then as a bytecode compiler and VM in C. This project ports the Java version to Swift.

This project is now complete 🎉.

Related Projects

  • bslox is my Swift port of the bytecode/VM, C version.

  • CompilerKit is a Swift collection data structures and algorithms that can be used in constructing a compiler.

Tests

The test suite is from the reference Java implementation. To run the tests:

$ swift build
$ ./test_swift.py chap13_inheritance

Almost all tests pass. The only two exceptions are class and method equality.

Goals & Design

The main goal is to write a Lox interpreter in Swift while demonstrating Swift's strengths. The project takes advantage of Swift's enums and extensions to implementer the interpreter in a type-safe, clear and concise way.

Enums for type safety. The reference Java implementation stores and exchanges all Lox data as Java Object types. This neccessates runtime type checks and coerced type casting. In this Swift implementation, enums are used instead to create a restricted and explicit set of possible Lox data types with the actual data attached as associated values to the enum cases in the correct Swift types. There's no type casting and the Any type (Swift's equivalent to Object) is not used in this project.

Enums make the visitor pattern redundant. As Bob Nystrom says in the book:

The Visitor pattern is really about approximating the functional style within an OOP language.

Fortunately, it's totally unnecessary in Swift! As a multi-paradigm programming laugnage, Swift has support for both the OOP and functional-styles of programming. Instead of using objects, the Swift version uses enum cases with associated values to represent the different kinds of expressions that get parsed. Different operations you need to perform on the expressions can then be written as simple recursive functions with a switch statement over the differet kinds of expressions.

This is an important improvement since the visitor pattern adds so much cruft and boilerplate code to the Java version that one of the first things you have to do is write a little code generator utility to produce the supporting Java code.

Extensions for better code organization. Swift's extensions allow you to add to an existing data type outside of its inital declaration. For example, the abstract syntax tree printer is written as a function in a source file separate from the expression data type, Expr. However, it is added to the Expr data type as a simple computed property that returns a string and can be accessed like this:

expression.ast

Without extensions, you would need to make an ast function that takes the expression as an argument. Since the function is now in the global namespace, it would be a bad idea to just call it ast. This is what the Java implementation looks like:

new AstPrinter().print(expression)

Alternatives

License

MIT