challenge BFコンパイラー

「どう書く?」でまだ出ていないのが不思議なお題。それがBF処理系。 ここでは、BFで書かれたソースを、同じ言語に変換するコンパイラーを募集します。

私自身、すでにPerlとJavaScriptに関しては http://blog.livedoor.jp/dankogai/archives/50545151.html でやっているのですが、他の言語バージョンも是非見たいので。

Dan the Brainf.ucker

以下のようにonelinerで可能です。 ただしLanguage::BF 0.03が必要です。 CodeRepos経由 で、

  • svn co svn.coderepos.org/share/lang/perl/Language-BF
  • cd Language-BF/trunk
  • perl Makefile.PL
  • make install

するか、CPANにVersion 0.03が現れるのをお待ち下さい。

Dan the Brainf.cker

1
2
3
4
perl -MLanguage::BF \
  -e 'print Language::BF->new_from_file(shift)->as_perl' t/hello.bf \
  | perl
Hello World!

Posted feedbacks - Scheme

無理矢理ですけど健全なマクロで解いてみました。

なお、出力されたコードもbf.scmを参照するのでロードパスを適切に設定しておく必要があります。

;;; bf-test.scm (サンプル)

(use bf)

(bf-compiler "+++++++++[>++++++++>+++++++++++>+++++<<<-]>.>++.+++++++..+++.>-.------------.<++++++++.--------.+++.------.--------.>+." 32)

;;; gosh bf-test.scm | gosh で"Hello, world!"が出力されます

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
;;; bf.scm
(define-module bf
  (export-all))

(define-syntax %bf-compiler
  (syntax-rules (< > + - |.| |,|)
    ((_ proc)
     proc)
    ((_ proc < rest ...)
     (%bf-compiler (compose (lambda (tape)
                              (cons (cons (cadr tape) (car tape))
                                    (cddr tape)))
                            proc)
                   rest ...))
    ((_ proc > rest ...)
     (%bf-compiler (compose (lambda (tape)
                              (cons (cdar tape)
                                    (cons (caar tape) (cdr tape))))
                            proc)
                   rest ...))
    ((_ proc + rest ...)
     (%bf-compiler (compose (lambda (tape)
                              (cons (car tape) (cons (modulo (+ (cadr tape) 1) 256)
                                                     (cddr tape))))
                            proc)
                   rest ...))
    ((_ proc - rest ...)
     (%bf-compiler (compose (lambda (tape)
                              (cons (car tape) (cons (modulo (- (cadr tape) 1) 256)
                                                     (cddr tape))))
                            proc)
                   rest ...))
    ((_ proc |.| rest ...)
     (%bf-compiler (compose (lambda (tape)
                              (write-byte (cadr tape))
                              (flush)
                              tape)
                            proc)
                   rest ...))     
    ((_ proc |,| rest ...)
     (%bf-compiler (compose (lambda (tape)
                              (let1 c (read-byte)
                              (cons (car tape)
                                    (cons (if (eof-object? c) 0 c) (cddr tape)))))
                            proc)
                   rest ...))                   
    ((_ proc [body ...] rest ...)
     (%bf-compiler (compose (lambda (tape)
                              (if (eq? (cadr tape) 0)
                                  tape
                                  (let1 f (%bf-compiler values body ...)
                                    (let loop ((t (f tape)))
                                      (if (eq? (cadr t) 0)
                                          t
                                          (loop (f t)))))))
                            proc)
                   rest ...))))

(define (bf-compiler str n)
  (write '(use bf))
  (write `((%bf-compiler values ,@(with-input-from-string
                              (regexp-replace-all #/[.,+-<>]/ #`"(,str)" "|\\0|")
                            read))
           ',(tape n))))
                              
(define (tape n)
  (let1 t (make-list n 0)
    (cons t t)))

(provide "bf")

ぐぁ、ポインタの進む向き逆にしてた。コードをあげなおします。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
;;; bf.scm
(define-module bf
  (export-all))

(define-syntax %bf-compiler
  (syntax-rules (< > + - |.| |,|)
    ((_ proc)
     proc)
    ((_ proc > rest ...)
     (%bf-compiler (compose (lambda (tape)
                              (cons (cons (cadr tape) (car tape))
                                    (cddr tape)))
                            proc)
                   rest ...))
    ((_ proc < rest ...)
     (%bf-compiler (compose (lambda (tape)
                              (cons (cdar tape)
                                    (cons (caar tape) (cdr tape))))
                            proc)
                   rest ...))
    ((_ proc + rest ...)
     (%bf-compiler (compose (lambda (tape)
                              (cons (car tape) (cons (modulo (+ (cadr tape) 1) 256)
                                                     (cddr tape))))
                            proc)
                   rest ...))
    ((_ proc - rest ...)
     (%bf-compiler (compose (lambda (tape)
                              (cons (car tape) (cons (modulo (- (cadr tape) 1) 256)
                                                     (cddr tape))))
                            proc)
                   rest ...))
    ((_ proc |.| rest ...)
     (%bf-compiler (compose (lambda (tape)
                              (write-byte (cadr tape))
                              (flush)
                              tape)
                            proc)
                   rest ...))     
    ((_ proc |,| rest ...)
     (%bf-compiler (compose (lambda (tape)
                              (let1 c (read-byte)
                              (cons (car tape)
                                    (cons (if (eof-object? c) 0 c) (cddr tape)))))
                            proc)
                   rest ...))                   
    ((_ proc [body ...] rest ...)
     (%bf-compiler (compose (lambda (tape)
                              (if (eq? (cadr tape) 0)
                                  tape
                                  (let1 f (%bf-compiler values body ...)
                                    (let loop ((t (f tape)))
                                      (if (eq? (cadr t) 0)
                                          t
                                          (loop (f t)))))))
                            proc)
                   rest ...))))

(define (bf-compiler str n)
  (write '(use bf))
  (write `((%bf-compiler values ,@(with-input-from-string
                              (regexp-replace-all #/[.,+-<>]/ #`"(,str)" "|\\0|")
                            read))
           ',(tape n))))
                              
(define (tape n)
  (let1 t (make-list n 0)
    (cons '() t)))

(provide "bf")

Index

Feed

Other

Link

Pathtraq

loading...