bf のサンプルコード(上記ウェブページから拾ってきたもの)
ハローワルド
自己コピー(ちょっと重い)
その2(結構重い)
skimu: とりあえず、モトネタです. (ソース bfi.scm)
% gosh bfi.scm hello.b Hello Wold! % gosh bfi.scm quine.b > q.b % gosh bfi.scm q.b > p.b % cmp p.b q.b
Shiro: bfi を次の3つの関数に置き換えます。 このバージョンでは、抽象的な「メモリ」の各バイトがクロージャで表現されています。 また、副作用を一切用いていません。変更が起こる度に新たなクロージャが作成 されます。 ちょいとトリッキーなのは、各「バイト」は直前と直後の「バイト」へのリンクを 保持しているため、隣の「バイト」がアップデートされた時は自分もアップデート (リンクを新しくした新たなクロージャを作成)しなければならないことです。 これは、オンデマンドで行われます (set-prev, set-nextコマンド)。
(define (make-pointer prev next value) (define (pointer cmd arg) (case cmd ((#\>) (if next (next 'set-prev pointer) (make-pointer pointer #f 0))) ((#\<) (if prev (prev 'set-next pointer) (error "pointer undeflow"))) ((set-prev) (if (eq? prev arg) pointer (make-pointer arg next value))) ((set-next) (if (eq? next arg) pointer (make-pointer prev arg value))) ((#\+) (make-pointer prev next (+ value 1))) ((#\-) (make-pointer prev next (- value 1))) ((#\.) (write-byte value) pointer) ((#\,) (make-pointer prev next (read-byte iport))) ((loop) (if (= value 0) pointer ((bfi2 arg pointer) 'loop arg))) )) pointer)
(define (bfi2 codes pointer) (cond ((null? codes) pointer) ((pair? (car codes)) (bfi2 (cdr codes) (pointer 'loop (car codes)))) (else (bfi2 (cdr codes) (pointer (car codes) #f)))))
(define (bfi codes) (bfi2 codes (make-pointer #f #f 0)))
skimu: scheme->bf はかなーりつらいのでとりあえず bf->Scheme です。:-) (ソース bfc.scm)
wugga% time gosh bfi.scm quine.b > /dev/null real 0m2.803s user 0m2.350s sys 0m0.140s wugga% time gosh bfi-no-side-effect.scm quine.b > /dev/null real 0m1.838s user 0m1.460s sys 0m0.150s wugga% gosh bfc.scm quine.b > bq.scm wugga% time gosh bq.scm > /dev/null real 0m0.575s user 0m0.380s sys 0m0.120s