# A kind of clone of dc geared towards binary operations.# by Paolo Bonzini## commands available:# conversion commands# b convert decimal to binary# d convert binary to decimal## arithmetic commands# < shift left binary by decimal number of bits (11 3< gives 11000)# > shift right binary by decimal number of bits (1011 2> gives 10)# & binary AND (between two binary operands)# | binary OR (between two binary operands)# ^ binary XOR (between two binary operands)# ~ binary NOT (between one binary operand)## stack manipulation commands# c clear stack# P pop stack top# D duplicate stack top# x exchange top two elements# r rotate stack counter-clockwise (second element becomes first)# R rotate stack clockwise (last element becomes first)## other commands# l print stack (stack top is first)# p print stack top# q quit, print stack top if any (cq is quiet quit)## The only shortcoming is that you'd better not attempt conversions of# values above 1000 or so.## This version does everything in pattern space (a la dc.sed).# --------------------------------------------------------------------------# This was actually used in a one-disk distribution of Linux to compute# netmasks as follows (1 parameter => compute netmask e.g. 24 becomes# 255.255.255.0; 2 parameters => given host address and netmask compute# network and broadcast addresses):## if [ $# = 1 ]; then# OUTPUT='$1.$2.$3.$4'# set 255.255.255.255 $1# else# OUTPUT='$1.$2.$3.$4 $5.$6.$7.$8'# fi## if [ `expr $2 : ".*\\."` -gt 0 ]; then# MASK="$2 br b8<r b16<r b24< R|R|R|"# else# MASK="$2b 31b ^d D# 11111111111111111111111111111111 x>1> x<1<"# fi## set `echo "$1 br b8<r b16<r b24< R|R|R| D # Load address# $MASK D ~r # Load mask## & DDD 24>dpP 16>11111111& dpP 8>11111111& dpP 11111111& dpP# | DDD 24>dpP 16>11111111& dpP 8>11111111& dpP 11111111& dpP# " | sed -f binary.sed`## eval echo $OUTPUT# --------------------------------------------------------------------------1s/^/%%/:cmds/\(.*%%\) *\([0-9][0-9]*\)/\2\\1/tcmds/%% *#.*/%%//%%$/ {$b quitN}/^.*%%D/ s/^[^\n]*\n/&&//^.*%%P/ s/^[^\n]*\n///^.*%%x/ s/^\([^\n]*\n\)\([^\n]*\n\)/\2\1//^.*%%r/ s/^\([^\n]*\n\)\([^%]*\)/\2\1//^.*%%R/ s/^\([^%]*\n\)\([^\n]*\n\)/\2\1//^.*%%c/ s/^.*%%/%%//^.*%%p/ P/^.*%%l/ {hs/.%%.*//pg}/^.*%%q/ {:quit/^%%/!Pd}/^.*%%b/ {# Decimal to binary via analog forms/^\([^\n]*\)/-&;9876543210aaaaaaaaa/:d2bloop1s/\(a*\)-\(.\)\([^;]*;[0-9]*\2.\{9\}\(a*\)\)/\1\1\1\1\1\1\1\1\1\1\4-\3/t d2bloop1s/-;9876543210aaaaaaaaa/;a01!/:d2bloop2s/\(a*\)\1\(a\{0,1\}\)\(;\2.\(.\)[^!]*!\)/\1\3\4//^a/b d2bloop2s/[^!]*!//}/^.*%%d/ {# Binary to decimal via analog forms/^\([^\n]*\)/-&;10a/:b2dloop1s/\(a*\)-\(.\)\([^;]*;[0-9]*\2.\(a*\)\)/\1\1\4-\3/t b2dloop1s/-;10a/;aaaaaaaaa0123456789!/:b2dloop2s/\(a*\)\1\1\1\1\1\1\1\1\1\(a\{0,9\}\)\(;\2.\{9\}\(.\)[^!]*!\)/\1\3\4//^a/b b2dloop2s/[^!]*!//}/^.*%%&/ {# Binary ANDs/\([^\n]*\)\n\([^\n]*\)/-\1-\2-111 01000/:andloops/\([^-]*\)-\([^-]*\)\([^-]\)-\([^-]*\)\([^-]\)-\([01 ]*\3\5\([01]\)\)/\7\1-\2-\4-\6/t andloops/^0*\([^-]*\)-[^\n]*/\1/s/^\n/0&/}/^.*%%^/ {# Binary XORs/\([^\n]*\)\n\([^\n]*\)/-\1-\2-000 01101/b orloop}/^.*%%|/ {# Binary ORs/\([^\n]*\)\n\([^\n]*\)/-\1-\2-000 10111/:orloops/\([^-]*\)-\([^-]*\)\([^-]\)-\([^-]*\)\([^-]\)-\([01 ]*\3\5\([01]\)\)/\7\1-\2-\4-\6/t orloops/\([^-]*\)-\([^-]*\)-\([^-]*\)-[^\n]*/\2\3\1/}/^.*%%~/ {# Binary NOTs/^\(.\)\([^\n]*\n\)/\1-010-\2/:notloops/\(.\)-0\{0,1\}\1\(.\)0\{0,1\}-\([01\n]\)/\2\3-010-/t notloop# If result is 00001..., \3 does not match (it looks for -10) and we just# remove the table and leading zeros. If result is 0000...0, \3 matches# (it looks for -0), \4 is a zero and we leave a lone zero as top of the# stack.s/0*\(1\{0,1\}\)\([^-]*\)-\(\1\(0\)\)\{0,1\}[^-]*-/\4\1\2/}/^.*%%</ {# Left shift, convert to analog and add a binary digit for each analog digits/^\([^\n]*\)/-&;9876543210aaaaaaaaa/:lshloop1s/\(a*\)-\(.\)\([^;]*;[0-9]*\2.\{9\}\(a*\)\)/\1\1\1\1\1\1\1\1\1\1\4-\3/t lshloop1s/^\(a*\)-;9876543210aaaaaaaaa\n\([^\n]*\)/\2\1/s/a/0/g}/^.*%%>/ {# Right shift, convert to analog and remove a binary digit for each analog digits/^\([^\n]*\)/-&;9876543210aaaaaaaaa/:rshloop1s/\(a*\)-\(.\)\([^;]*;[0-9]*\2.\{9\}\(a*\)\)/\1\1\1\1\1\1\1\1\1\1\4-\3/t rshloop1s/^\(a*\)-;9876543210aaaaaaaaa\n\([^\n]*\)/\2\1/:rshloop2s/.a//s/^aa*/0//a\n/b rshloop2}s/%%./%%/tcmd