Lisp49 - A primitive Scheme
A year or so ago, I wrote this small interactive interpreter as a tool to help with some other work I was doing. It might be of some general interest to anybody interested in Scheme.

It’s almost an R5RS-compliant Scheme. It doesn’t use any third-party libraries, except for the STL and the C runtime. It supports continuations, bignums, ML-style pattern matching, and the parser supports nested quoting/backquoting (use ‘ to quote and ` to backquote within a quoted expression). It does not support macros or ports.
There’s no “standard prelude” defined, and all of the available functions are printed out on the console as soon as you start the interpreter. You can bootstrap a familiar environment with the following set of definitions:
(define foldl (lambda (iv fn lst) (if (= lst nil) iv (foldl (fn iv (head lst)) fn (tail lst)))))
(define foldr (lambda (iv fn lst) (if (= lst nil) iv (fn (head lst) (foldr iv fn (tail lst))))))
(define map (lambda (fn lst) (foldr nil (lambda (a b) (pair (fn a) b)) lst)))
(define filter (lambda (fn lst) (foldr nil (lambda (a b) (if (fn a) (pair a b) b)) lst)))
(define append (lambda (v1 v2) (foldr v2 (lambda (a b) (pair a b)) v1)))
(define + (lambda (~nums) (foldl 0 prim+ nums)))
(define - (lambda (~nums) (foldl 0 prim- nums)))
(define * (lambda (~nums) (foldl 1 prim* nums)))
(define >= (lambda (v1 v2) (if (> v1 v2) t (if (= v1 v2) t nil))))
(define <= (lambda (v1 v2) (if (< v1 v2) t (if (= v1 v2) t nil))))
You can test the bignum support with ye olde factorial:
> (define fact (lambda (n) (if (= n 0) 1 (prim* n (fact (prim- n 1))))))
> (fact 50)
30414093201713378043612608166064768844377641568960512000000000000
You can test the pattern-matching like so:
(case ‘(integer 5)
(’(string ?s) (concat “Hello, ” s))
(’(bool ?b) (if b “True!” “False!”))
(’(integer ?n) n)
)
And you could test the continuation support with this example, escaping a map:
> (define nat+
(lambda (inc nums)
(call/cc
(lambda (return)
(map
(lambda (num) (if (>= num 0) (prim+ num inc) (return “Error: nat+ is only defined over positive numbers.”)))
nums)))))
> (nat+ 1 ‘(1 2 3 4 5))
(2 3 4 5 6)
> (nat+ 1 ‘(1 2 3 4 5 -2 5 4 3 2 1))
“Error: nat+ is only defined over positive numbers.”
Enter “show-unsweeten” at the prompt to show the result of the “unsweeten transform” (a transform that removes syntactic sugar for if, let, letrec, let*, case, etc). Enter “show-cps” to show the CPS transform of expressions before they’re evaluated.

