-
Notifications
You must be signed in to change notification settings - Fork 0
/
bf.php
113 lines (94 loc) · 2.52 KB
/
bf.php
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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
<?php
// Brainfuck PHP interpreter.
// Ver: 0.1
// 2020.07.31 [email protected]
function show_help() {
echo('Brainfuck PHP interpreter.'."\n");
echo('$ php bh.php <BF Source Code>.'."\n");
}
// bf file name.
if (isset($argv[1])) {
// help mode.
if($argv[1] == '-h') { show_help(); exit(0); }
// input file name
else { $fn = $argv[1]; }
} else { show_help(); exit(1); }
// debug mode flag.
if(isset($argv[2]) && $argv[2] == '-v') { $flg_debug = true; }
else { $flg_debug = false; }
// 配列
$bf_data[0] = 0;
// 配列のポインタ
$bf_pointer = 0;
// 実行中の命令のアドレス
$bf_addr = 0;
// ループで戻ってくるアドレス
$bf_lpbk = 0;
$src = file_get_contents($fn);
if ( $src === false) {
echo('Error - not open bf souce code.'."\n");
exit(1);
}
// $bf_source[$bf_pointer] = 1byte bf command.
$bf_source = str_split($src);
while( $bf_addr < count($bf_source) ) {
// for debuging.
if ($flg_debug) { var_dump($bf_addr.' - '.$bf_source[$bf_addr]); }
if ($flg_debug) { var_dump($bf_data); }
switch($bf_source[$bf_addr]) {
// inc
case '+':
$bf_data[$bf_pointer]++;
break;
// dec
case '-':
$bf_data[$bf_pointer]--;
break;
// input
case ',':
$in = trim(fgets(STDIN));
$in = substr( $in, 0, 1);
$bf_data[$bf_pointer] = hexdec(bin2hex($in));
unset($in);
break;
// output
case '.':
switch($bf_data[$bf_pointer]) {
case 10:
echo("\n");
break;
case 13:
echo("\r");
break;
default:
echo(hex2bin(dechex($bf_data[$bf_pointer])));
break;
}
break;
// pointer shift right
case '>':
$bf_pointer++;
if (!isset($bf_data[$bf_pointer])) { $bf_data[$bf_pointer] = 0; }
break;
// pointer shift left
case '<':
$bf_pointer--;
break;
// start loop
case '[':
// loop back point
$bf_lpbk = $bf_addr;
break;
// end loop
case ']':
if ($bf_data[$bf_pointer] == 0) {
$bf_lpbk = 0;
} else {
// jump to loop back point
$bf_addr = $bf_lpbk;
}
break;
}
$bf_addr++;
}
exit(0);