brainfuck on AWK
某授業のTAとしてawkを教えることになり、この予習中に思わぬ流れで発見した@naoya_t氏のブログ(http://blog.livedoor.jp/naoya_t/archives/51026653.html)にあったGrass on AWKに感銘を受けて、ならばbrainfuck on AWKをつくらねば!と思い作ってみたもの
一応以下の典型的なhelloworldプログラムは動いたのできっと大丈夫でしょう。
+++++++++[>++++++++>+++++++++++>+++++<<<-]>.>++.+++++++..+++.>-. ------------.<++++++++.--------.+++.------.--------.>+.
いろいろなところが甘そうな気がするけど気にしない気にしない
BEGIN{ # source constructions char_pos = 0; char_end = 0; sources = ""; # used for source manip bfk_string[0] = 0; current_pos = 0; # tape tape[0] = 0; tape_pos = 0; } {#for each line num_char = split($0,array_str, ""); i = 1; while(i <= num_char) { j = i -1; bfk_string[char_pos + j] = array_str[i]; i++; } char_pos = char_pos + num_char; char_end = char_pos; } function do_func(char) { if( char == ">" ) { dprint("inc pointer"); inc_pointer(); } if( char == "<" ) { dprint("dec pointer"); dec_pointer(); } if( char == "+" ) { dprint("add"); inc_current_value(); } if( char == "-" ) { dprint("sub"); dec_current_value(); } if( char == "." ) { dprint("show"); print_current_value_char(); } } function inc_pointer() { tape_pos++; } function dec_pointer() { tape_pos--; } function inc_current_value() { if(tape[tape_pos] == "") { tape[tape_pos] = 0; } tape[tape_pos]++; return tape[tape_pos]; } function dec_current_value() { if(tape[tape_pos] == "") { tape[tape_pos] = 0; } tape[tape_pos]--; return tape[tape_pos]; } function print_current_value_char() { printf("%c",tape[tape_pos]); } function get_current_value(){ return tape[tape_pos]; } function get_next_char() { if( current_pos > char_end){ return 0; } this_char = bfk_string[current_pos]; current_pos++; return this_char; } function jump_forward() { cur = get_current_value(); if ( cur != 0 ) { return; } stack_count = 0; while(1){ char = get_next_char(); if( char == 0 ){ # end of file printf("ERROR - no match clauses\n"); exit; } if( char == "[" ) { # stack stack_count+=1; continue; } if( char == "]" ) { if( stack_count > 0 ) { stack_count -= 1; continue; } # stack_count == 0 break; } } } function jump_backward() { stack_count = 0; cur = get_current_value(); if( cur == 0 ){ return; } if( current_pos < 2 ){ printf("ERROR - guess only ] appears first?") } while( current_pos > -1 ){ current_pos = current_pos - 2; char = get_next_char(); if ( char == 0 ) { #end of file printf("ERROR - no match clauses\n"); exit; } if( char == "]" ) { stack_count += 1; continue; } if( char == "[" ) { if( stack_count > 0 ) { stack_count -= 1; continue; } # stack_count == 0 break; } } } function dprint(str) { # printf("%s\n",str); } END { # here bfk_string is array of source string # char_end indicates end of the source array while(1) { char = get_next_char(); if( char == ""){ dprint("end of file"); exit; } if( char == "[" ){ jump_forward(); continue; } if( char == "]" ) { jump_backward(); continue; } do_func(char); } }