Skip to content


Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?

Latest commit


Git stats


Failed to load latest commit information.
Latest commit message
Commit time


A lightweight (~550 lines of code) Lisp interpreter with Scheme dialect. I was inspired to make this after watching all the SICP lectures.


  • file inclusion e.g. (include test.scm), can be nested inside files
  • optimized tail recursion
  • first class procedures and by extension higher order procedures
  • lexical scoping so you don't have to worry about local variables clashing in called procedures
  • free typed arguments, e.g. (define (add x) ...) x is expected by the semantics to be a list, but not enforced
  • local binding (essentially giving code blocks) with keyword let
  • ; comments

Get boost
I originally intended to include the boost parts required, but as you can see from include_list, you're better off getting the proper boost distribution. To compensate, this repository contains a binary built on Ubuntu 14.04 which should work on most Unix based machines.


(include funcs.scm)     ; don't do this! recursive inclusion is bad D:

(define (if test a b) (cond ((test) a) (else b)))

(define compose (lambda (f g)   ; fundamental higher order procedure
        (lambda (x)
                (f (g x)))))

(define expt (lambda (x n)      ; exponential 
              (cond ((= n 1) x)
                    (else (* x 
                             (expt x (- n 1)))))))

(define nth-power (lambda (n)
        (lambda (x)
                (expt x n))))

(define square (nth-power 2))

(define cube (nth-power 3))

(define square_and_cube (compose square cube))

(define (add x)
        (cond ((empty? x) 0)
              (else (+ (car x) (add (cdr x))))))

(begin (do something) (do somethingelse) result)    ; basic sequencing

(define (add4 n)
        (let ((x 4)) (+ x n)))  ; basic local binding

(cat 'something 'somethingelse)

(square 5)

(add (1 2 3 4))


  • build by typing "make" in the same directory
  • build benchmark version by replacing main.cpp with timing.cpp in makefile
  • list parameters (such as x for add above) treated same as 'normal' parameters
  • interpret files with ./clisp [filename] [-p], add -p or -print option to force printing of file evaluation, silent by default (assumes a lot of definitions)
    • include files with (include filename), which can be nested
  • build debug information (with step by step info) by changing build target and source in makefile to "testing" and "testing.cpp" respectively
  • requires a compiler supporting C++11
  • uses boost::variant (link above)
  • keywords (so far): define, lambda, cond, cons, cdr, list, else, and, or, not, empty?, include, begin
  • use 'quote to signify string
    • string will raise an error if it's not defined, but 'string will return string
  • use cat primitive instead of + to concatenate strings
  • expressions can extend over different lines, terminated by appropriate )!


Lisp interpreter in C++






No releases published


No packages published