mirror of
https://https.git.savannah.gnu.org/git/sed.git
synced 2026-01-27 18:05:01 +00:00
(automatically generated log message) git-archimport-id: bonzini@gnu.org--2004b/sed--stable--4.1--base-0
227 lines
5.0 KiB
Sed
227 lines
5.0 KiB
Sed
# 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 keeps the stack in hold space and the command in pattern
|
|
# space; it is the fastest one (though the gap with binary3.sed is small).
|
|
# --------------------------------------------------------------------------
|
|
# 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
|
|
# --------------------------------------------------------------------------
|
|
|
|
:cmd
|
|
s/^[\n\t ]*//
|
|
s/^#.*//
|
|
/^$/ {
|
|
$b quit
|
|
N
|
|
t cmd
|
|
}
|
|
/^[0-9][0-9]*/ {
|
|
G
|
|
h
|
|
s/^[0-9][0-9]* *\([^\n]*\).*/\1/
|
|
x
|
|
s/^\([0-9][0-9]*\)[^\n]*/\1/
|
|
x
|
|
t cmd
|
|
}
|
|
|
|
/^[^DPxrRcplqbd&|^~<>]/b bad
|
|
|
|
/^D/ {
|
|
x
|
|
s/^[^\n]*\n/&&/
|
|
}
|
|
/^P/ {
|
|
x
|
|
s/^[^\n]*\n//
|
|
}
|
|
/^x/ {
|
|
x
|
|
s/^\([^\n]*\n\)\([^\n]*\n\)/\2\1/
|
|
}
|
|
/^r/ {
|
|
x
|
|
s/^\([^\n]*\n\)\(.*\)/\2\1/
|
|
}
|
|
/^R/ {
|
|
x
|
|
s/^\(.*\n\)\([^\n]*\n\)/\2\1/
|
|
}
|
|
/^c/ {
|
|
x
|
|
s/.*//
|
|
}
|
|
/^p/ {
|
|
x
|
|
P
|
|
}
|
|
|
|
/^l/ {
|
|
x
|
|
p
|
|
}
|
|
|
|
/^q/ {
|
|
:quit
|
|
x
|
|
/./P
|
|
d
|
|
}
|
|
|
|
/^b/ {
|
|
# Decimal to binary via analog form
|
|
x
|
|
s/^\([^\n]*\)/-&;9876543210aaaaaaaaa/
|
|
:d2bloop1
|
|
s/\(a*\)-\(.\)\([^;]*;[0-9]*\2.\{9\}\(a*\)\)/\1\1\1\1\1\1\1\1\1\1\4-\3/
|
|
t d2bloop1
|
|
s/-;9876543210aaaaaaaaa/;a01!/
|
|
:d2bloop2
|
|
s/\(a*\)\1\(a\{0,1\}\)\(;\2.\(.\)[^!]*!\)/\1\3\4/
|
|
/^a/b d2bloop2
|
|
s/[^!]*!//
|
|
}
|
|
|
|
/^d/ {
|
|
# Binary to decimal via analog form
|
|
x
|
|
s/^\([^\n]*\)/-&;10a/
|
|
:b2dloop1
|
|
s/\(a*\)-\(.\)\([^;]*;[0-9]*\2.\(a*\)\)/\1\1\4-\3/
|
|
t b2dloop1
|
|
s/-;10a/;aaaaaaaaa0123456789!/
|
|
:b2dloop2
|
|
s/\(a*\)\1\1\1\1\1\1\1\1\1\(a\{0,9\}\)\(;\2.\{9\}\(.\)[^!]*!\)/\1\3\4/
|
|
/^a/b b2dloop2
|
|
s/[^!]*!//
|
|
}
|
|
|
|
/^&/ {
|
|
# Binary AND
|
|
x
|
|
s/\([^\n]*\)\n\([^\n]*\)/-\1-\2-111 01000/
|
|
:andloop
|
|
s/\([^-]*\)-\([^-]*\)\([^-]\)-\([^-]*\)\([^-]\)-\([01 ]*\3\5\([01]\)\)/\7\1-\2-\4-\6/
|
|
t andloop
|
|
s/^0*\([^-]*\)-[^\n]*/\1/
|
|
s/^\n/0&/
|
|
}
|
|
|
|
/^\^/ {
|
|
# Binary XOR
|
|
x
|
|
s/\([^\n]*\)\n\([^\n]*\)/-\1-\2-000 01101/
|
|
b orloop
|
|
}
|
|
|
|
/^|/ {
|
|
# Binary OR
|
|
x
|
|
s/\([^\n]*\)\n\([^\n]*\)/-\1-\2-000 10111/
|
|
:orloop
|
|
s/\([^-]*\)-\([^-]*\)\([^-]\)-\([^-]*\)\([^-]\)-\([01 ]*\3\5\([01]\)\)/\7\1-\2-\4-\6/
|
|
t orloop
|
|
s/\([^-]*\)-\([^-]*\)-\([^-]*\)-[^\n]*/\2\3\1/
|
|
}
|
|
|
|
/^~/ {
|
|
# Binary NOT
|
|
x
|
|
s/^\(.\)\([^\n]*\n\)/\1-010-\2/
|
|
:notloop
|
|
s/\(.\)-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 digit
|
|
x
|
|
s/^\([^\n]*\)/-&;9876543210aaaaaaaaa/
|
|
:lshloop1
|
|
s/\(a*\)-\(.\)\([^;]*;[0-9]*\2.\{9\}\(a*\)\)/\1\1\1\1\1\1\1\1\1\1\4-\3/
|
|
t lshloop1
|
|
s/^\(a*\)-;9876543210aaaaaaaaa\n\([^\n]*\)/\2\1/
|
|
s/a/0/g
|
|
}
|
|
|
|
/^>/ {
|
|
# Right shift, convert to analog and remove a binary digit for each analog digit
|
|
x
|
|
s/^\([^\n]*\)/-&;9876543210aaaaaaaaa/
|
|
:rshloop1
|
|
s/\(a*\)-\(.\)\([^;]*;[0-9]*\2.\{9\}\(a*\)\)/\1\1\1\1\1\1\1\1\1\1\4-\3/
|
|
t rshloop1
|
|
s/^\(a*\)-;9876543210aaaaaaaaa\n\([^\n]*\)/\2\1/
|
|
:rshloop2
|
|
s/.a//
|
|
s/^aa*/0/
|
|
/a\n/b rshloop2
|
|
}
|
|
|
|
x
|
|
:bad
|
|
s/^.//
|
|
tcmd
|