forked from drakedevel/bbf
-
Notifications
You must be signed in to change notification settings - Fork 0
/
bbf.sh
91 lines (89 loc) · 1.49 KB
/
bbf.sh
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
#!/bin/bash
if [[ -z $1 ]]; then
echo "Usage: bbf.sh <foo.bf>"
fi
exec 3<>"$1"
# Load
declare -i pc=0
declare -a code
declare -i sp=0
declare -a stack
declare -A linkage
while read -u 3 -d "" -n 1 op; do
case "$op" in
"["|"]")
if [[ "$op" == "[" ]]; then
stack[$sp]=$pc
((sp++))
else
if [[ $sp -eq 0 ]]; then
echo "mismatched ]" >&2
exit 1
fi
((sp--))
linkage[$pc]=${stack[$sp]}
linkage[${stack[$sp]}]=$((pc + 1))
fi
;&
">"|"<"|"+"|"-"|"."|",")
code[$pc]="$op"
((pc++))
;;
esac
done
if [[ $sp -ne 0 ]]; then
echo "mismatched ["
exit 1
fi
# Execute
declare -i ptr=0
declare -A tape
pc=0
while [[ $pc -lt ${#code[@]} ]]; do
case "${code[$pc]}" in
">")
((ptr++))
;;
"<")
((ptr--))
;;
"+")
if [[ -z ${tape[$ptr]} ]]; then
tape[$ptr]=1
else
((tape[$ptr] = (tape[$ptr] + 1) % 256))
fi
;;
"-")
if [[ -z ${tape[$ptr]} ]]; then
tape[$ptr]=255
else
((tape[$ptr] = (tape[$ptr] + 255) % 256))
fi
;;
".")
echo -en "\\x$(printf "%02x" ${tape[$ptr]})"
;;
",")
hex=$(dd bs=1 count=1 2>/dev/null | xxd -ps)
if [[ -n "$hex" ]]; then
tape[$ptr]=$((16#$hex))
else
tape[$ptr]=0
fi
;;
"[")
if [[ -z ${tape[$ptr]} || ${tape[$ptr]} -eq 0 ]]; then
pc=${linkage[$pc]}
continue
fi
;;
"]")
if [[ -n ${tape[$ptr]} && ${tape[$ptr]} -ne 0 ]]; then
pc=${linkage[$pc]}
continue
fi
;;
esac
((pc++))
done