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 - diff

自己ツッコミ。
このままだと"~[]~" のようなBFコードがあった際にwhile文のところで文法エラーを起こすので、
']'が出た時にはpassをダミーで放り込んだ方がよさそうです。


あと、最初間違えてインタプリタを書いてしまった名残で変なやり方になっていました。
 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
def encode(bfcode):
-   depth = code = 0 
+   depth = 0
    pycode = []
    stack = []
    
    f = file(default['-o'], 'w')
    
    pycode.append('import sys')
-   pycode.append('tape, ptr, code = {}, 0, 0')
+   pycode.append('tape, ptr = {}, 0')
    

-     while code != len(bfcode):
-        c = bfcode[code]
+     for c in bfcode:
        if c == '>':
            pycode.append('\t' * depth + 'ptr += 1')
        elif c == '<':
            pycode.append('\t' * depth + 'ptr -= 1')
        elif c == '+':
            pycode.append('\t' * depth + 'tape[ptr] = tape.get(ptr, 0) + 1')
        elif c == '-':
            pycode.append('\t' * depth + 'tape[ptr] = tape.get(ptr, 0) - 1')
        elif c == ',':
            pycode.append('\t' * depth + 'tape[ptr] = sys.stdin.read(1)')
        elif c == '.':
            pycode.append('\t' * depth + 'sys.stdout.write(chr(tape.get(ptr, 0)))')
        elif c == '[':
            pycode.append('\t' * depth + 'while tape.get(ptr, 0):')
            stack.append(depth)
            depth += 1
        elif c == ']':
+           pycode.append('\t' * depth + 'pass')
            depth = stack.pop()

-    code += 1

書き換えてみました。echo はそれらしい動きをしています。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
@@ -4,7 +4,7 @@
   | '+' -> "incr code.(!p);"
   | '-' -> "decr code.(!p);"
   | '.' -> "print_char (char_of_int !(code.(!p)));"
-  | ',' -> "code.(!p) := read_char ();"
+  | ',' -> "code.(!p) := input_byte stdin;"
   | '[' -> "while 0 <> !(code.(!p)) do"
   | ']' -> "done;;"
   |  _  -> ""  ;;
@@ -14,7 +14,6 @@
   Printf.printf "\
     let stackincr x = if %d < (incr x; !x) then x:=0;;\n\
     let stackdecr x = if 0 > (decr x; !x) then x:=%d;;\n\
-    let read_char () = int_of_char (read_line () ).[0];;\n\
     let code = Array.init %d (fun i -> ref 0);;\n\
     let p = ref 0;;\n\n"
     (stacksize-1) (stacksize-1) stacksize;

Index

Feed

Other

Link

Pathtraq

loading...