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 66 s/^[\n\t ]*// 67 s/^#.*// 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 223 x 224 :bad 225 s/^.// 226 tcmd 227