Skip to content

LemonPi/Clisp

master
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?
Code

Latest commit

 

Git stats

Files

Permalink
Failed to load latest commit information.
Type
Name
Latest commit message
Commit time
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

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++

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published