LemonPi / Clisp

Lisp interpreter in C++

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Clisp


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

Features:

  • 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.

Example:

(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))

Tips:

  • 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 )!

About

Lisp interpreter in C++


Languages

Language:C++ 95.8%Language:Scheme 3.5%Language:Makefile 0.7%