A simple little Scheme-derived language implemented in Ruby.
Blueprint is still tiny, missing a ton of functionality, and has absolutely atrocious performance. This is all just for fun.
To fire up a REPL:
$ bin/run_repl > (+ 1 2 3) 6 >
(Consider using rlwrap for readline functionality--use
Blueprint supports a lot of the functionality you'd expect from a Scheme (though some of its syntax is a bit different):
(read "(+ 1 2 3)") # => '(+ 1 2 3) (eval '(+ 1 2 3)) # => 6
(define (fact n) (if (== n 0) 1 (* n (fact (- n 1))))) (fact 6) # => 72
(define (make-counter) (let ((n 0)) (lambda () (set! n (+ 1 n))))) (define a (make-counter)) (define b (make-counter)) (a) # => 1 (a) # => 2 (b) # => 1
(define (drop-two (a b . rest) rest)) (drop-two 1 2 3 4 5 6) # => '(3 4 5 6)
Blueprint is completely dynamic; it does everything at runtime. As such, it
doesn't have a separate macro-expansion phase and uses fexprs to handle forms
where the evaluation of arguments needs to be delayed. Fexprs are non-hygienic
(like Common Lisp's macros). Blueprint also emulates Common Lisp-style macros by
supporting quasiquoting with backticks, commas, and
,@ for splicing, which
makes writing fexprs convenient:
(deffexpr (unless condition consequent alternative) `(if (not ,condition) ,consequent ,alternative))
Blueprint doesn't yet have a
gensym facility, though, so watch out for
variable capture! That should be coming shortly.
One of Blueprint's goals is to make everything
applyable, including fexprs:
(deffexpr (adder x) `(+ 1 ,x)) (map adder '(1 2 3)) # => '(2 3 4)
Even special forms like
quote are first-class, applicable
(map first '((1 2) (3 4))) # => '(1 3)
Blueprint has a standard library that defines some basic functions and fexprs,
Blueprint's test coverage is pretty good. The tests for the interpreter are written in RSpec, while the tests for the standard library are written in Blueprint itself.
To run all of the tests: