images/subs.png

listening to.

playing.

hello.

thanks for visiting! I'm erik, and I'll be a junior in computer science here at cu next fall. I'm interested in most any topic in computer science, maybe especially programming languages and the theory of computation, right now.

if you'd like to contact me, send an email!

my projects.

jeme is a compiler for the scheme programming language that generates JVM bytecode. I'm bootstrapping the compiler with mzscheme, but the end goal is for it to be self-hosting. it's hosted at google code.

jeme.png

most recently I've been working on implementing a syntax-rules macro system; I've made some progress, and am currently trying to identify and fix bugs.

here is a short example (from macros that work) of how the compiler might process some code that defines and uses a simple macro:

;; push.scm
(define-syntax push
  (syntax-rules ()
    ((push ?v ?x)
     (set! ?x (cons ?v ?x)))))

(define (main args)
  (let ((pros (list "cheap" "fast"))
        (cons (list)))
    (push "unreliable" cons)
    (display cons)
    (newline)))

the syntax expander walks the parse tree of this code, looking for macro calls to expand. it expands define, let, and push, and then returns a new parse tree which it passes along to the code generator.

;; expanded
(define main
  (lambda (_gs3_)
    ((lambda (_gs5_ _gs6_)
       (set! _gs6_ (cons "unreliable" _gs6_))
       (display _gs6_)
       (newline))
     (list "cheap" "fast")
     (list))))
// compiled
...
62:  iconst_2
63:  anewarray       #70; //class jeme/lang/SchemeObject
66:  dup
67:  iconst_0
68:  new             #72; //class jeme/lang/SchemeString
71:  dup
72:  ldc             #74; //String unreliable
74:  invokespecial   #77; //Method jeme/lang/SchemeString."<init>"
77:  aastore
78:  dup
79:  iconst_1
80:  getstatic       #56; //Field p1:Lpush;
...

at this point, because main was defined as a procedure of one argument, we have an executable java class:

% mzscheme -t compiler.scm -m push.scm
% java push
("unreliable")

in the future, I would like to possibly try to add some sort of optimizations (e.g., especially for self-recursive tail-calls), and continue to implement more of the scheme language and standard library. I only plan to support escape continuations, i.e., that just throw an Exception (and aren't first-class).

it would be really cool to have an interface to java classes (and a macro for defining them), but I'll have to think more about how to best implement this.

turing machine simulator is a pretty trivial piece of code I wrote to model turing machines with scheme. using it, here is how we might define a machine that writes a 1 if its input is odd length, and writes 0 otherwise:

(define odd-length?
  '((start . 1)
    ((1 . a) 2 _ . R)
    ((2 . a) 1 _ . R)
    ((1 . _) 3 0 . R)
    ((2 . _) 3 1 . R)
    (accept . 3)))

simulate runs a machine with a given input "tape," which is just a list of symbols. so for example, (simulate odd-length? '(a a a)) returns (_ _ _ 1) and (simulate odd-length? '(a a)) returns (_ _ 0).

(define (simulate machine tape)
  (let ((accept (accept-state machine)))
    (let loop ((state (start-state machine))
               (tape (cons '() tape)))
      (if (or (not state) (eq? accept state))
          (append (reverse (car tape))
                  (cdr tape))
          (let ((next (step machine state tape)))
            (loop (car next) (cdr next)))))))

the procedure write-machine will write a DOT file for a machine, that can be used to create pictures:

odd-length.png

I've posted the rest of the code to tm-simulator.scm, in case anyone is interested. as far as I know, this is all portable R5RS except for maybe one line in write-machine that's specific to mzscheme.

self-enumerating pangrams is a project that I've wanted to work on for while but that only now I hope to get started. The goal is to, given a prefix and a set of symbols, generate a sentence that begins with the prefix and then enumerates itself for the specified symbols.

for example, (sep "This sentence contains" '(#\a #\b)), where sep is the program, might return "This sentence contains three a's and one b." as I get started, I'll store my code in pangrams.scm.

js-scheme is an interpreter for a small subset of the scheme programming language written in javascript. it's hosted right here, for now.

an alternate version of the interpreter is written in cps so that it can provide re-invokable continuations. this is of limited use as the javascript stack will overflow very quickly. the regular interpreter comes with "plug-ins" for last.fm and flot.

> (define (generate-one-element-at-a-time lst)
..  (define (generator)
..    (call/cc control-state))
..  (define (control-state return)
..    (for-each
..     (lambda (element)
..       (set! return 
..             (call/cc
..               (lambda (resume-here)
..                 (set! control-state resume-here)
..                 (return element)))))
..     lst)
..    (return 'you-fell-off-the-end))
..  generator)
;Value: generate-one-element-at-a-time
> (define generate-digit
..  (generate-one-element-at-a-time '(0 1 2)))
;Value: generate-digit
> (generate-digit)
;Value: 0
> (generate-digit)
;Value: 1
> (generate-digit)
;Value: 2
> (generate-digit)
;Value: you-fell-off-the-end