Schemin is a BSD-licensed scheme-ish interpreter, written in C#. Schemin is complete enough to run some simple scheme snippets, such as this example bubblesort routine:
(define bubblesort (lambda (l) (define swap-pass (lambda (l) (if (= (length l) 1) l (let ((fst (car l))(snd (cadr l))(rest (cddr l))) (if (> fst snd) (cons snd (swap-pass (cons fst rest))) (cons fst (swap-pass (cons snd rest)))))))) (let for ((times (length l)) (val l)) (if (> times 1) (for (- times 1)(swap-pass val)) (swap-pass val))))) As well as some more complicated things, like this simple example of coroutines using call/cc:
(define (superfluous-computation do-other-stuff) (let loop () (map (lambda (graphic) (display graphic) (newline) (set! do-other-stuff (call/cc do-other-stuff))) '("Straight up." "Quarter after." "Half past." "Quarter til.")) (loop))) (define (hefty-computation do-other-stuff) (let loop ((n 5)) (display "Hefty computation: ") (display n) (newline) (set! do-other-stuff (call/cc do-other-stuff)) (display "Hefty computation (b)") (newline) (set! do-other-stuff (call/cc do-other-stuff)) (display "Hefty computation (c)") (newline) (set! do-other-stuff (call/cc do-other-stuff)) (if (> n 0) (loop (- n 1))))) (hefty-computation superfluous-computation) Or this explicit-renaming macro, which implements an "unless" construct:
(define-rewriter unless (lambda (form rename) `(,(rename 'if) (,(rename 'not) ,(cadr form)) ,(caddr form)))) Check out the examples directory for more examples of what Schemin is capable of, or the src/ScheminLib directory for portions of Schemin implemented in itself.
- Lexically scoped macros, that are hopefully not totally broken.
- All primitive types in r5rs, except the full numerical tower.
- First-class continuations and call/cc
- IO Ports (File and console IO)
- define and set!
- lambdas with closures
- Let, named let, Let*, and letrec
- Some flow control (if, cond, and, or and boolean primitives)
- A few list operations like map, filter, and foldl (as well as cons, cdr, car, etc)
- Some basic numerical primitives and decimal support
- Implement more common primitives
- Implement hygenic macros
- Implement proper tail-call optimization