• 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 in hold space and the command in pattern
34# space; it is the fastest one (though the gap with binary3.sed is small).
35# --------------------------------------------------------------------------
36# This was actually used in a one-disk distribution of Linux to compute
37# netmasks as follows (1 parameter => compute netmask e.g. 24 becomes
38# 255.255.255.0; 2 parameters => given host address and netmask compute
39# network and broadcast addresses):
40#
41# if [ $# = 1 ]; then
42#   OUTPUT='$1.$2.$3.$4'
43#   set 255.255.255.255 $1
44# else
45#   OUTPUT='$1.$2.$3.$4 $5.$6.$7.$8'
46# fi
47#
48# if [ `expr $2 : ".*\\."` -gt 0 ]; then
49#   MASK="$2 br b8<r b16<r b24< R|R|R|"
50# else
51#   MASK="$2b 31b ^d D
52#         11111111111111111111111111111111 x>1> x<1<"
53# fi
54#
55# set `echo "$1 br b8<r b16<r b24< R|R|R| D    # Load address
56#            $MASK D ~r                        # Load mask
57#
58#            & DDD 24>dpP 16>11111111& dpP 8>11111111& dpP 11111111& dpP
59#            | DDD 24>dpP 16>11111111& dpP 8>11111111& dpP 11111111& dpP
60#       " | sed -f binary.sed`
61#
62# eval echo $OUTPUT
63# --------------------------------------------------------------------------
64
65:cmd
66s/^[\n\t ]*//
67s/^#.*//
68/^$/ {
69  $b quit
70  N
71  t cmd
72}
73/^[0-9][0-9]*/ {
74  G
75  h
76  s/^[0-9][0-9]* *\([^\n]*\).*/\1/
77  x
78  s/^\([0-9][0-9]*\)[^\n]*/\1/
79  x
80  t cmd
81}
82
83/^[^DPxrRcplqbd&|^~<>]/b bad
84
85/^D/ {
86  x
87  s/^[^\n]*\n/&&/
88}
89/^P/ {
90  x
91  s/^[^\n]*\n//
92}
93/^x/ {
94  x
95  s/^\([^\n]*\n\)\([^\n]*\n\)/\2\1/
96}
97/^r/ {
98  x
99  s/^\([^\n]*\n\)\(.*\)/\2\1/
100}
101/^R/ {
102  x
103  s/^\(.*\n\)\([^\n]*\n\)/\2\1/
104}
105/^c/ {
106  x
107  s/.*//
108}
109/^p/ {
110  x
111  P
112}
113
114/^l/ {
115  x
116  p
117}
118
119/^q/ {
120  :quit
121  x
122  /./P
123  d
124}
125
126/^b/ {
127  # Decimal to binary via analog form
128  x
129  s/^\([^\n]*\)/-&;9876543210aaaaaaaaa/
130  :d2bloop1
131  s/\(a*\)-\(.\)\([^;]*;[0-9]*\2.\{9\}\(a*\)\)/\1\1\1\1\1\1\1\1\1\1\4-\3/
132  t d2bloop1
133  s/-;9876543210aaaaaaaaa/;a01!/
134  :d2bloop2
135  s/\(a*\)\1\(a\{0,1\}\)\(;\2.\(.\)[^!]*!\)/\1\3\4/
136  /^a/b d2bloop2
137  s/[^!]*!//
138}
139
140/^d/ {
141  # Binary to decimal via analog form
142  x
143  s/^\([^\n]*\)/-&;10a/
144  :b2dloop1
145  s/\(a*\)-\(.\)\([^;]*;[0-9]*\2.\(a*\)\)/\1\1\4-\3/
146  t b2dloop1
147  s/-;10a/;aaaaaaaaa0123456789!/
148  :b2dloop2
149  s/\(a*\)\1\1\1\1\1\1\1\1\1\(a\{0,9\}\)\(;\2.\{9\}\(.\)[^!]*!\)/\1\3\4/
150  /^a/b b2dloop2
151  s/[^!]*!//
152}
153
154/^&/ {
155  # Binary AND
156  x
157  s/\([^\n]*\)\n\([^\n]*\)/-\1-\2-111 01000/
158  :andloop
159  s/\([^-]*\)-\([^-]*\)\([^-]\)-\([^-]*\)\([^-]\)-\([01 ]*\3\5\([01]\)\)/\7\1-\2-\4-\6/
160  t andloop
161  s/^0*\([^-]*\)-[^\n]*/\1/
162  s/^\n/0&/
163}
164
165/^\^/ {
166  # Binary XOR
167  x
168  s/\([^\n]*\)\n\([^\n]*\)/-\1-\2-000 01101/
169  b orloop
170}
171
172/^|/ {
173  # Binary OR
174  x
175  s/\([^\n]*\)\n\([^\n]*\)/-\1-\2-000 10111/
176  :orloop
177  s/\([^-]*\)-\([^-]*\)\([^-]\)-\([^-]*\)\([^-]\)-\([01 ]*\3\5\([01]\)\)/\7\1-\2-\4-\6/
178  t orloop
179  s/\([^-]*\)-\([^-]*\)-\([^-]*\)-[^\n]*/\2\3\1/
180}
181
182/^~/ {
183  # Binary NOT
184  x
185  s/^\(.\)\([^\n]*\n\)/\1-010-\2/
186  :notloop
187  s/\(.\)-0\{0,1\}\1\(.\)0\{0,1\}-\([01\n]\)/\2\3-010-/
188  t notloop
189
190  # If result is 00001..., \3 does not match (it looks for -10) and we just
191  # remove the table and leading zeros.  If result is 0000...0, \3 matches
192  # (it looks for -0), \4 is a zero and we leave a lone zero as top of the
193  # stack.
194
195  s/0*\(1\{0,1\}\)\([^-]*\)-\(\1\(0\)\)\{0,1\}[^-]*-/\4\1\2/
196}
197
198/^</ {
199  # Left shift, convert to analog and add a binary digit for each analog digit
200  x
201  s/^\([^\n]*\)/-&;9876543210aaaaaaaaa/
202  :lshloop1
203  s/\(a*\)-\(.\)\([^;]*;[0-9]*\2.\{9\}\(a*\)\)/\1\1\1\1\1\1\1\1\1\1\4-\3/
204  t lshloop1
205  s/^\(a*\)-;9876543210aaaaaaaaa\n\([^\n]*\)/\2\1/
206  s/a/0/g
207}
208
209/^>/ {
210  # Right shift, convert to analog and remove a binary digit for each analog digit
211  x
212  s/^\([^\n]*\)/-&;9876543210aaaaaaaaa/
213  :rshloop1
214  s/\(a*\)-\(.\)\([^;]*;[0-9]*\2.\{9\}\(a*\)\)/\1\1\1\1\1\1\1\1\1\1\4-\3/
215  t rshloop1
216  s/^\(a*\)-;9876543210aaaaaaaaa\n\([^\n]*\)/\2\1/
217  :rshloop2
218  s/.a//
219  s/^aa*/0/
220  /a\n/b rshloop2
221}
222
223x
224:bad
225s/^.//
226tcmd
227