• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# A kind of clone of dc geared towards binary operations.
2# by Paolo Bonzini
3#
4# commands available:
5#   conversion commands
6#     b      convert decimal to binary
7#     d      convert binary to decimal
8#
9#   arithmetic commands
10#     <      shift left binary by decimal number of bits (11 3< gives 11000)
11#     >      shift right binary by decimal number of bits (1011 2> gives 10)
12#     &      binary AND (between two binary operands)
13#     |      binary OR (between two binary operands)
14#     ^      binary XOR (between two binary operands)
15#     ~      binary NOT (between one binary operand)
16#
17#   stack manipulation commands
18#     c      clear stack
19#     P      pop stack top
20#     D      duplicate stack top
21#     x      exchange top two elements
22#     r      rotate stack counter-clockwise (second element becomes first)
23#     R      rotate stack clockwise (last element becomes first)
24#
25#   other commands
26#     l      print stack (stack top is first)
27#     p      print stack top
28#     q      quit, print stack top if any (cq is quiet quit)
29#
30# The only shortcoming is that you'd better not attempt conversions of
31# values above 1000 or so.
32#
33# This version keeps the stack and the current command in hold space and
34# the commands in pattern space; it is just a bit slower than binary2.sed
35# but more size optimized for broken seds which have a 199-command limit
36# (though binary2.sed does not have this much).
37#
38# --------------------------------------------------------------------------
39# This was actually used in a one-disk distribution of Linux to compute
40# netmasks as follows (1 parameter => compute netmask e.g. 24 becomes
41# 255.255.255.0; 2 parameters => given host address and netmask compute
42# network and broadcast addresses):
43#
44# if [ $# = 1 ]; then
45#   OUTPUT='$1.$2.$3.$4'
46#   set 255.255.255.255 $1
47# else
48#   OUTPUT='$1.$2.$3.$4 $5.$6.$7.$8'
49# fi
50#
51# if [ `expr $2 : ".*\\."` -gt 0 ]; then
52#   MASK="$2 br b8<r b16<r b24< R|R|R|"
53# else
54#   MASK="$2b 31b ^d D
55#         11111111111111111111111111111111 x>1> x<1<"
56# fi
57#
58# set `echo "$1 br b8<r b16<r b24< R|R|R| D    # Load address
59#            $MASK D ~r                        # Load mask
60#
61#            & DDD 24>dpP 16>11111111& dpP 8>11111111& dpP 11111111& dpP
62#            | DDD 24>dpP 16>11111111& dpP 8>11111111& dpP 11111111& dpP
63#       " | sed -f binary.sed`
64#
65# eval echo $OUTPUT
66# --------------------------------------------------------------------------
67
68:cmd
69s/^[\n\t ]*//
70s/^#.*//
71/^$/ {
72  $b quit
73  N
74  t cmd
75}
76/^[0-9][0-9]*/ {
77  G
78  h
79  s/^[0-9][0-9]* *\([^\n]*\).*/\1/
80  x
81  s/^\([0-9][0-9]*\)[^\n]*/\1/
82  x
83  t cmd
84}
85
86/^[^DPxrRcplqbd&|^~<>]/bbad
87
88H
89x
90s/\(\n[^\n]\)[^\n]*$/\1/
91
92/D$/ s/^[^\n]*\n/&&/
93/P$/ s/^[^\n]*\n//
94/x$/ s/^\([^\n]*\n\)\([^\n]*\n\)/\2\1/
95/r$/ s/^\([^\n]*\n\)\(.*\)\(..\)/\2\1\3/
96/R$/ s/^\(.*\n\)\([^\n]*\n\)\(..\)/\2\1\3/
97/c$/ s/.*//
98/p$/ P
99/l$/ {
100  s/...$//
101  p
102  t cmd
103}
104
105/q$/ {
106  :quit
107  /.../P
108  d
109}
110
111/b$/ {
112  # Decimal to binary via analog form
113  s/^\([^\n]*\)/-&;9876543210aaaaaaaaa/
114  :d2bloop1
115  s/\(a*\)-\(.\)\([^;]*;[0-9]*\2.\{9\}\(a*\)\)/\1\1\1\1\1\1\1\1\1\1\4-\3/
116  t d2bloop1
117  s/-;9876543210aaaaaaaaa/;a01!/
118  :d2bloop2
119  s/\(a*\)\1\(a\{0,1\}\)\(;\2.\(.\)[^!]*!\)/\1\3\4/
120  /^a/b d2bloop2
121  s/[^!]*!//
122}
123
124/d$/ {
125  # Binary to decimal via analog form
126  s/^\([^\n]*\)/-&;10a/
127  :b2dloop1
128  s/\(a*\)-\(.\)\([^;]*;[0-9]*\2.\(a*\)\)/\1\1\4-\3/
129  t b2dloop1
130  s/-;10a/;aaaaaaaaa0123456789!/
131  :b2dloop2
132  s/\(a*\)\1\1\1\1\1\1\1\1\1\(a\{0,9\}\)\(;\2.\{9\}\(.\)[^!]*!\)/\1\3\4/
133  /^a/b b2dloop2
134  s/[^!]*!//
135}
136
137/&$/ {
138  # Binary AND
139  s/\([^\n]*\)\n\([^\n]*\)/-\1-\2-111 01000/
140  :andloop
141  s/\([^-]*\)-\([^-]*\)\([^-]\)-\([^-]*\)\([^-]\)-\([01 ]*\3\5\([01]\)\)/\7\1-\2-\4-\6/
142  t andloop
143  s/^0*\([^-]*\)-[^\n]*/\1/
144  s/^\n/0&/
145}
146
147/\^$/ {
148  # Binary XOR
149  s/\([^\n]*\)\n\([^\n]*\)/-\1-\2-000 01101/
150  b orloop
151}
152
153/|$/ {
154  # Binary OR
155  s/\([^\n]*\)\n\([^\n]*\)/-\1-\2-000 10111/
156  :orloop
157  s/\([^-]*\)-\([^-]*\)\([^-]\)-\([^-]*\)\([^-]\)-\([01 ]*\3\5\([01]\)\)/\7\1-\2-\4-\6/
158  t orloop
159  s/\([^-]*\)-\([^-]*\)-\([^-]*\)-[^\n]*/\2\3\1/
160}
161
162/~$/ {
163  # Binary NOT
164  s/^\(.\)\([^\n]*\n\)/\1-010-\2/
165  :notloop
166  s/\(.\)-0\{0,1\}\1\(.\)0\{0,1\}-\([01\n]\)/\2\3-010-/
167  t notloop
168
169  # If result is 00001..., \3 does not match (it looks for -10) and we just
170  # remove the table and leading zeros.  If result is 0000...0, \3 matches
171  # (it looks for -0), \4 is a zero and we leave a lone zero as top of the
172  # stack.
173
174  s/0*\(1\{0,1\}\)\([^-]*\)-\(\1\(0\)\)\{0,1\}[^-]*-/\4\1\2/
175}
176
177/<$/ {
178  # Left shift, convert to analog and add a binary digit for each analog digit
179  s/^\([^\n]*\)/-&;9876543210aaaaaaaaa/
180  :lshloop1
181  s/\(a*\)-\(.\)\([^;]*;[0-9]*\2.\{9\}\(a*\)\)/\1\1\1\1\1\1\1\1\1\1\4-\3/
182  t lshloop1
183  s/^\(a*\)-;9876543210aaaaaaaaa\n\([^\n]*\)/\2\1/
184  s/a/0/g
185}
186
187/>$/ {
188  # Right shift, convert to analog and remove a binary digit for each analog digit
189  s/^\([^\n]*\)/-&;9876543210aaaaaaaaa/
190  :rshloop1
191  s/\(a*\)-\(.\)\([^;]*;[0-9]*\2.\{9\}\(a*\)\)/\1\1\1\1\1\1\1\1\1\1\4-\3/
192  t rshloop1
193  s/^\(a*\)-;9876543210aaaaaaaaa\n\([^\n]*\)/\2\1/
194  :rshloop2
195  s/.a//
196  s/^aa*/0/
197  /a\n/b rshloop2
198}
199
200s/..$//
201x
202:bad
203s/^.//
204tcmd
205