Brainfuck interpreter added by anonymous on Fri Aug 9 15:39:03 2013

(use srfi-1)
(use extras)
(use utils)

(define vm (make-vector 500 0))
(define ptr 0)
(define pc 0)

(define (main)
  (let* ([port (open-input-file (last (argv)))]
         [data (read-all port)]
         [char (string-ref data pc)])
    (cond
      [(char=? char #\>) (set! ptr (add1 ptr))]
      [(char=? char #\<) (set! ptr (sub1 ptr))]
      [(char=? char #\+) (vector-set! vm ptr (add1 (vector-ref vm ptr)))]
      [(char=? char #\-) (vector-set! vm ptr (sub1 (vector-ref vm ptr)))]
      [(char=? char #\.) (write-byte (vector-ref vm ptr))]
      [(char=? char #\,) (vector-set! vm ptr (read-byte))]
      [(char=? char #\[) (when (= (vector-ref vm ptr) 0)
                           (let* ([depth 1] [loop (lambda ()
                                                   (set! pc (add1 pc)) ; Does this change the value of pc globally?
                                                   (cond
                                                     [(char=? (string-ref data pc) #\[) (set! depth (add1 depth))]
                                                     [(char=? (string-ref data pc) #\]) (set! depth (sub1 depth))]))])
                             (if (and (> depth 0) (not (char=? (string-ref data pc) #\]))) (loop))))]
      [(char=? char #\]) (when (not (= (vector-ref vm ptr) 0))
                           (let* ([depth 1] [loop (lambda ()
                                                   (set! pc (sub1 pc)) ; Does this change the value of pc globally?
                                                   (cond
                                                     [(char=? (string-ref data pc) #\]) (set! depth (add1 depth))]
                                                     [(char=? (string-ref data pc) #\[) (set! depth (sub1 depth))]))])
                             (if (and (> depth 0) (not (char=? (string-ref data pc) #\[))) (loop))))])
    (set! pc (add1 pc))
    (close-input-port port)
    (if (not (= (string-length data) pc)) (main))))

(main)