Unlambda
In December 2004 I wrote a simple interpreter for the Unlambda programming language. It represents Unlambda functions as Scheme functions, which saves a great deal of work.
You can download unlambda.scm.
; Simple Unlambda Interpreter
; Load this file, then call (unlambda "`r`.d`.l`.r`.o`.w`. `.,`.o`.l`.l`.e`.hi")
; Note: each built in function does its own substitution.
(define (eval-u ex e)
(cond ((eq? ex 'k) (lambda (f) (lambda (g) f)))
((eq? ex 's) (lambda (f) (lambda (g) (lambda (h)
(eval-u (list (list f h) (list g h)) e)))))
((eq? ex 'i) (lambda (f) f))
((eq? ex 'v) ((lambda (h) (lambda (x) (h h)))
(lambda (h) (lambda (x) (h h)))))
((eq? ex 'c) call/cc)
((eq? ex 'd) 'unlambda-delay)
((eq? ex 'r) (make-print "\n"))
((eq? ex 'e) e)
((procedure? ex) ex)
((pair? ex) (let ((f (eval-u (car ex) e)))
(if (eq? f 'unlambda-delay)
(lambda (h) (eval-u (list (cadr ex) h) e))
(f (eval-u (cadr ex) e)))))))
(define (parse-u flat cont)
(cond ((equal? (car flat) #\.) (cont (make-print (cadr flat)) (cddr flat)))
((member (car flat) (string->list "ksivcdre"))
(cont (string->symbol (string (car flat))) (cdr flat)))
((equal? (car flat) #\`)
(parse-u (cdr flat) (lambda (f rest)
(parse-u rest (lambda (g rest)
(cont (list f g) rest))))))
(else (parse-u (cdr flat) cont))))
(define (unlambda->s-exp source)
(if (string? source)
(unlambda->s-exp (string->list source))
(parse-u source (lambda (tree rest)
(if (not (null? rest))
(error "Extra characters: " (list->string rest))
tree)))))
(define (unlambda source)
(call/cc (lambda (e) (eval-u (unlambda->s-exp source) e)))
(display ""))
(define (make-print x) (lambda (f) (display x) f))