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