Summary: Tolk README
Table of Contents
Key Claims
- Tolk is a Common Lisp library for writing interpreters, following PLAI ch. by ch. but using CL/CLOS instead of plai-typed/Racket.
- Each interpreter lives in its own package to avoid naming clashes; one file
per interpreter in
src/, one test file intests/. - AST nodes are CLOS classes inheriting from
ast-node;defmethoddispatch on class replacestype-case. - The
defmethod-bindmacro (fromtolk/utils) combinesdefmethodwith slot binding via metabang-bind, avoiding boilerplate. trivia/ quasiquote patterns (via fare-quasiquote) are used for parsing s-expressions.- The arithmetic interpreter introduces
parse,interpret, andexecuteas the three key generic functions. - Tests use
fiveam;eqo(object equality) compares AST nodes structurally. - The Racket reader (
tolk/reader) reads.rktfiles, checking for#lang racketheader, producing a list of s-expressions for the parser.
Summary
Tolk is the course implementation repository for Advprog. It implements a growing series of interpreters in Common Lisp, one per PLAI chapter / language feature. The architecture is:
tolk/
src/
utils.lisp ← defmethod-bind, env/store utilities
parser-combinators.lisp
racket/
reader.lisp ← reads .rkt files to s-expression lists
arith.lisp ← arithmetic interpreter (PLAI ch.3)
python/ ← Python subset interpreter (later)
tests/
object-equality.lisp ← eqo for structural AST comparison
racket/
reader.lisp
arith.lisp
Interpreter development workflow
For each new language:
- Open
src/{name}.lisp; define package, export symbols. - Add
(:file "{name}")totolk.asd. - Add
tests/{name}.lispwith fiveam tests. - Add
(:file "{name}")to the test system intolk.asd. - Run
(asdf:test-system :tolk).
Key design choices vs. PLAI
| PLAI (plai-typed) | Tolk (Common Lisp) |
|---|---|
define-type / type-case |
defclass hierarchy + defmethod dispatch |
Single polymorphic parse |
defgeneric parse + methods for sexp and pathname |
| Returns bare number | Returns number (arith); richer values later |
| Typed s-expressions | Native CL values (no casting needed) |
plai-typed's test |
fiveam (test ...) / (is ...) |
defmethod-bind pattern
The macro defmethod-bind (see Defmethod-bind) allows methods to be written as:
(defmethod-bind interpret ((num n))
()
n)
instead of the more verbose:
(defmethod interpret ((inst num))
(bind (((:slots n) inst))
n))
The first argument to defmethod-bind is (class-name slot-name...) not
(instance-name class-name) as in defmethod. It uses closer-mop to inspect
slots at macro-expansion time, which is why all AST class definitions in tolk
are wrapped in eval-when (:compile-toplevel :load-toplevel :execute).
See Defmethod-bind for the full explanation.