LoginSignup
3
3

More than 5 years have passed since last update.

D言語で書く "イケメンなコード" ~ Brainfuck処理系をワンライナーで書く ~

Last updated at Posted at 2016-02-06

ワンライナーでBrainfuck処理系を書きました。
発端は自分が開発しているBrainfuck処理系(GitHub - alphaKAI/brainfuck)を高速化している時に、ふとこれ、ワンライナー化出来るのでは...?と考え、書いてみたら出来ました。
例によってZ Combinatorによる無名再帰を多用しています
一部型を省略可能な場所がありますが可読性のために残してあります。
(注意: 複雑なコードだと単純な再帰になっているためスタックオーバーフローを起こしてしまい、実行できません....)

完全なワンライナーにしました!!

では、以下に完成したコードを貼ります

import std.algorithm,
       std.array,
       std.stdio,
       std.string,
       std.conv;
import core.memory;


R delegate(Args) Z(R, Args...)(R delegate(R delegate(Args), Args) f){
  return (Args args) => f(Z(f), args);
}

void main() {
  ((string input) =>
    (operators =>
      ((char* code) =>
        ((ubyte* memory) =>
          ((ulong memoryIndex) =>
            (removeTrash =>
              (process =>
                process(input)
              )((string input) =>
                  ((string[] _code) =>
                    (
                      (
                        GC.realloc(code,   _code.length *  char.sizeof, GC.BlkAttr.NO_SCAN | GC.BlkAttr.APPENDABLE),
                        GC.realloc(memory, _code.length * ubyte.sizeof, GC.BlkAttr.NO_SCAN | GC.BlkAttr.APPENDABLE)
                      ),
                      Z((int delegate(int) copy, int i) => i < _code.length ? (code[i] = _code[i].to!char, copy(i + 1)) : 0)(0),
                      ((int pc) =>
                        (optimizer =>
                          ((int delegate() destructor) =>
                            ((int[int] brackets) =>
                              (process =>
                                (
                                  process(int.init),
                                  destructor()
                                )
                              )(Z((int delegate(int) process, int index) =>
                                  index < _code.length 
                                  ? ((char current) =>
                                      (
                                        (current == '>'
                                          ? memoryIndex++
                                       : current == '<'
                                          ? memoryIndex--
                                       : current == '+'
                                          ? memory[memoryIndex]++
                                       : current == '-'
                                          ? memory[memoryIndex]--
                                       : current == '.'
                                          ? (
                                              write(memory[memoryIndex].to!char),
                                              stdout.flush()
                                            )
                                       : current == ','
                                         ? ((string buf) =>
                                              (
                                                Z((int delegate() getLine) => ((buf = readln()) == null || !buf.length) ? getLine() : 0)(),
                                                memory[memoryIndex] = cast(ubyte)buf[0]
                                              )
                                           )(string.init)
                                       : current == '['
                                         ? (memory[memoryIndex] == 0 ? (index = brackets[index], 0) : 0)
                                       : current == ']'
                                         ? (memory[memoryIndex] != 0 ? (index = brackets[index], 0) : 0)
                                       : 0
                                        ),
                                        process(index + 1)
                                      )
                                    )(code[index])
                                  : 0
                                ))
                            )(optimizer(int.init, (int[]).init, (int[int]).init))
                          )(() => (GC.free(code), GC.free(memory), memoryIndex = 0, 0))
                        )(Z((int[int] delegate(size_t, int[], int[int]) optimizer, size_t i, int[] leftstack, int[int] brackets) => 
                            i < _code.length ? 
                              ((char c) =>
                                !canFind(operators, _code[i])
                                  ? optimizer(i + 1, leftstack, brackets)
                                  : (
                                      c == '['
                                        ? (optimizer(i + 1, leftstack ~ pc++, brackets)) 
                                        : (c == ']' && leftstack.length != 0)
                                            ? (left =>
                                                (leftstack.popBack(),
                                                  (right =>
                                                    (
                                                      (brackets[left] = right, brackets[right] = left),
                                                      pc++,
                                                      optimizer(i + 1, leftstack, brackets)
                                                    )
                                                  )(pc))
                                              )(leftstack[$ - 1])
                                            : (pc++, optimizer(i + 1, leftstack, brackets))
                                    )
                              )(code[i]) : brackets
                            )
                        )
                      )(int.init)
                    )
                )(removeTrash(input))
              )
            )((string key) => key.split("").filter!(x => operators.canFind(x)).array)
          )(ulong.init)
        )(cast(ubyte*)GC.malloc(300000 * ubyte.sizeof, GC.BlkAttr.NO_SCAN | GC.BlkAttr.APPENDABLE))
      )(cast(char*) GC.malloc(300000 *  char.sizeof, GC.BlkAttr.NO_SCAN | GC.BlkAttr.APPENDABLE))
    )([">", "<", "+", "-", ".", ",", "[", "]"])
  )(">+++++++++[<++++++++>-]<.>+++++++[<++++>-]<+.+++++++..+++.[-]>++++++++[<++++>-]<.>+++++++++++[<+++++>-]<.>++++++++[<+++>-]<.+++.------.--------.[-]>++++++++[<++++>-]<+.[-]++++++++++.");
// => Hello World!
}
3
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3