{"id":21391161,"url":"https://github.com/kelnos/slox","last_synced_at":"2025-07-13T17:30:45.248Z","repository":{"id":41447396,"uuid":"109081573","full_name":"kelnos/slox","owner":"kelnos","description":"A scala implementation of an interpreter for the lox language (see http://www.craftinginterpreters.com)","archived":false,"fork":false,"pushed_at":"2017-12-15T03:19:18.000Z","size":143,"stargazers_count":5,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-07T15:21:15.475Z","etag":null,"topics":["interpreter","lox-language","programming-language","scala"],"latest_commit_sha":null,"homepage":"","language":"Scala","has_issues":false,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/kelnos.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-11-01T03:19:42.000Z","updated_at":"2024-04-29T00:11:46.000Z","dependencies_parsed_at":"2022-08-25T13:31:02.282Z","dependency_job_id":null,"html_url":"https://github.com/kelnos/slox","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/kelnos/slox","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kelnos%2Fslox","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kelnos%2Fslox/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kelnos%2Fslox/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kelnos%2Fslox/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kelnos","download_url":"https://codeload.github.com/kelnos/slox/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kelnos%2Fslox/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":265178331,"owners_count":23723240,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["interpreter","lox-language","programming-language","scala"],"created_at":"2024-11-22T13:24:09.978Z","updated_at":"2025-07-13T17:30:44.995Z","avatar_url":"https://github.com/kelnos.png","language":"Scala","funding_links":[],"categories":[],"sub_categories":[],"readme":"# slox\n\n`slox` is a Scala implementation of an interpreter for the Lox language\nused in the [Crafting Interpreters][ci] book.  I decided that following\nalong and using Java (like the book does) would be too easy (heh), and I\nwanted to write the interpreter in Scala, in an idiomatic (functional,\nimmutable data, type-safer, `null`-free, exception-free, etc.) way.\n\nI did a quick search and didn't find any other Scala implementations,\nthough admittedly it was a *very* quick search.\n\n## Usage\n\n### Building\n\nGrab the [sbt launcher script][sbtl] and put it somewhere in your\n`PATH`.  Then run:\n\n```\nmake assembly\n```\n\n### Running\n\nTo run the REPL, just run:\n\n```\nmake run\n```\n\nTo run a `.lox` script, run:\n\n```\nmake run SCRIPT=/path/to/script.lox\n```\n\n## Deviations\n\nThere are a few differences between my version of Lox and the\n'canonical' one.\n\n### Bad\n\n* The parser and interpreter use a lot of recursion.  Some of the\n  functions in question are able to make use of tail-call optimization,\n  but many calls are not.  Stack overflows may be possible while running\n  certain Lox programs.\n* This actually isn't a deviation, but it's \"bad\" from my perspective:\n  so far I've implemented LoxInstance (for class instances) using a\n  mutable data member (*gasp*).  I'll get around to finding an immutable\n  soluion for that eventually that doesn't deviate too far from the\n  script.\n\n### Middling\n\n* Instead of hand-writing the scanner, I decided to use Scala's\n  [parser-combinators package][spc] to build one.  It seemed like a fun\n  exercise to learn how to use it, though this means I missed out on\n  writing my own.  I guess I'll get to dive into that when we get to the\n  C version.\n\n### Good\n\nThis is also a list of extras in the \"CHALLENGES\" section at the end of\neach chapter that I've gotten around to implementing so far.\n\n* I've implemented type coercions for concatenating strings with other\n  types.\n* I've made it a runtime error to divide by zero.\n* My scanner preserves comments, and strips them after scanning but\n  before parsing.  It even supports nested multiline comments.\n* I've implemented error productions for attempts to use binary\n  operators where a unary operator is expected.\n* The `continue` and `break` keywords work inside `for` and `while`\n  loops.\n* I've implemented anonymous functions.\n* It prints a warning for each unused local variable.\n* Classes support static methods.  I deviated from the challenge in the\n  book here and used `fun` inside a class body to denote a static\n  method, instead of `class` as suggested.  Using `fun` just seems more\n  natural to me, and also leaves open the possibility of using `class`\n  inside a class body to support inner classes.\n* Classes support 'getters' (property access that runs a block of code).\n* I've implemented a fairly-easy way to build builtin classes, and added\n  simple `List` and `File` classes, as well as a `System` class with\n  some system-related functions.\n* A fairly large departure: I've implemented support for exceptions and\n  try/catch/finally statements.\n* Typical of Scala programs, I eschew using `null` as the internal\n  representation of Lox's `nil`, and instead repesent it as a distict\n  type of literal.\n* Since Scala has `case classes` and class-based pattern matching, I\n  don't use any codegen for the expression/statement types, or use the\n  visitor pattern.\n\n## Thanks\n\nJust wanted to give a quick note of thanks to Bob Nystrom, the author of\nCrafting Interpreters.  I always thought PL and compiler/interpreter\ndevelopment was a scary black art.  While I do think it's still\nsomething of a black art, I'm beginning to see it's not all that scary.\nHis book is amazingly accessible and well written.  I'm looking forward\nto the rest of the chapters, and highly recommend [reading it][ci] if\nyou're at all interested in this topic.\n\n[ci]: https://www.craftinginterpreters.com/\n[sbtl]: https://raw.githubusercontent.com/paulp/sbt-extras/master/sbt\n[spc]: https://github.com/scala/scala-parser-combinators\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkelnos%2Fslox","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkelnos%2Fslox","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkelnos%2Fslox/lists"}