Scalisp — a Lisp Interpreter in Scala
An interpreter for a small Lisp dialect written in Scala, with a REPL and file execution — special forms and built-in functions live in their own packages.

An interpreter for a small Lisp dialect, written in Scala — with a REPL and file execution. After a “Programming Languages” course I got curious about how interpreters actually work, and Lisp, with its uniform syntax, fits that curiosity better than most languages.
The Problem
The interpreter needs to execute the basic forms (define, if, lambda, let, and similar) plus a set of built-in functions.
Architecture
Special forms — the ones the interpreter handles before evaluating their arguments (if, define, lambda) — live in the evaluator package, while ordinary built-in functions — the ones that evaluate their arguments first and then apply (arithmetic, list operations) — live in builtins.
- src/main/scala/
- ast/Abstract syntax tree (AST) and value types
- Expr.scala
- Value.scala
- builtins/Built-in functions and operations
- ArithmeticOps.scalaArithmetic operations
- Builtins.scalaRegisters built-in functions and operations
- ComparisonOps.scalaComparison operations
- ListOps.scalaList operations
- entrypoint/Program entry point
- FileRunner.scala
- REPL.scala
- env/The interpreter's environment, storing variables and functions
- evaluator/Logic for evaluating AST expressions
- parser/Parses source code into an AST
- utils/Utilities for printing and formatting output
How to Run
The just utility is the easiest way to run the REPL or a file:
just repl # REPL
just run path/to/file.lsp # run a file
Without just — directly through sbt:
sbt run
sbt "runMain entrypoint.runFile path/to/file.lsp"