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