1 module optimize; 2 3 import brainfuck; 4 5 import std.algorithm.iteration; 6 import std.algorithm.searching; 7 import std.array; 8 import std.range; 9 import std.conv; 10 11 BrainfuckInstruction[] clear_opt(BrainfuckInstruction[] insts) { 12 return insts.map!(inst => delegate BrainfuckInstruction() { 13 if(auto loop = cast(Loop) inst) { 14 auto loop_insts = loop.insts; 15 if(loop_insts.length == 1) { 16 if(auto modify = cast(Modify) loop_insts[0]) { 17 if(modify.amt == -1) return new Clear(); 18 } 19 } 20 21 return new Loop(clear_opt(loop.insts)); 22 } 23 24 return inst; 25 }()).array; 26 } 27 28 BrainfuckInstruction[] balanced_opt(BrainfuckInstruction[] insts) { 29 return insts.map!(inst => delegate BrainfuckInstruction() { 30 if(auto loop = cast(Loop) inst) { 31 auto loop_insts = loop.insts; 32 if(loop_insts.all!(loop_inst => (cast(Modify) loop_inst) || (cast(Select) loop_inst))) { 33 if(loop_insts 34 .filter!(loop_inst => cast(Select) loop_inst) 35 .map!(loop_inst => (cast(Select) loop_inst).amt) 36 .sum() == 0) { 37 int[int] ms; 38 int pointer = 0; 39 40 foreach(loop_inst; loop_insts) { 41 if(auto modify = cast(Modify) loop_inst) { 42 ms[pointer] += modify.amt; 43 } else if(auto select = cast(Select) loop_inst) { 44 pointer += select.amt; 45 } 46 } 47 48 if(ms[0] == -1) { 49 ms.remove(0); 50 return new MoveLoop(ms); 51 } 52 } 53 } 54 55 return new Loop(balanced_opt(loop.insts)); 56 } 57 58 return inst; 59 }()).array; 60 }