RosettaCodeData/Task/Execute-Brain----/Ol/execute-brain----.ol

41 lines
2.0 KiB
Plaintext

(define (bf program stack-length)
(let ((program (string-append program "]"))
(program-counter 0)
(stack (make-vector stack-length 0))
(stack-pointer 0))
(letrec ((skip (lambda (PC sp)
(let loop ((pc PC) (sp sp))
(let ((ch (string-ref program pc))
(pc (+ pc 1)))
(case ch
(#\] (list pc sp))
(#\[ (apply loop (skip pc sp)))
(else
(loop pc sp)))))))
(step (lambda (PC SP)
(let loop ((pc PC) (sp SP))
(let ((ch (string-ref program pc))
(pc (+ pc 1)))
(case ch
(#\] (list (- PC 1) sp))
(#\[ (if (eq? (vector-ref stack sp) 0)
(apply loop (skip pc sp))
(apply loop (step pc sp))))
(#\+ (set-ref! stack sp (+ (vector-ref stack sp) 1))
(loop pc sp))
(#\- (set-ref! stack sp (- (vector-ref stack sp) 1))
(loop pc sp))
(#\> (loop pc (+ sp 1)))
(#\< (loop pc (- sp 1)))
(#\. (display (make-string 1 (vector-ref stack sp)))
(loop pc sp))
(else
(loop pc sp))))))))
(step 0 0))))
; testing:
; (bf ",++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>." 30000)
; ==> Hello World!
; (bf ">>++++[<++++[<++++>-]>-]<<.[-]++++++++++." 30000)
; ==> @