# $OpenBSD: math.sed,v 1.1 2008/10/10 14:33:34 millert Exp $ # # from: @(#)math.sed 8.1 (Berkeley) 6/6/93 # # Addition and multiplication in sed. # ++ for a limited time only do (expr) too!!! # # Kevin S Braunsdorf, PUCC UNIX Group, ksb@cc.purdue.edu. # # Ex: # echo "4+7*3" | sed -f %f # make sure the expression is well formed s/[ ]//g /[+*\/-]$/{ a\ poorly formed expression, operator on the end q } /^[+*\/]/{ a\ poorly formed expression, leading operator q } # fill hold space with done token x s/^.*/done/ x # main loop, process operators (*, + and () ) : loop /^\+/{ s/// b loop } /^\(.*\)(\([^)]*\))\(.*\)$/{ H s//\2/ x s/^\(.*\)\n\(.*\)(\([^()]*\))\(.*\)$/()\2@\4@\1/ x b loop } /^[0-9]*\*/b mul /^\([0-9]*\)\+\([0-9+*]*\*[0-9]*\)$/{ s//\2+\1/ b loop } /^[0-9]*\+/{ s/$/=/ b add } x /^done$/{ x p d } /^()/{ s/// x G s/\(.*\)\n\([^@]*\)@\([^@]*\)@\(.*\)/\2\1\3/ x s/[^@]*@[^@]*@\(.*\)/\1/ x b loop } i\ help, stack problem p x p q # turn mul into add until 1*x -> x : mul /^0*1\*/{ s/// b loop } /^\([0-9]*\)0\*/{ s/^\([0-9]*\)0\*\([0-9]*\)/\1*\20/ b mul } s/^\([0-9]*\)1\*/\10*/ s/^\([0-9]*\)2\*/\11*/ s/^\([0-9]*\)3\*/\12*/ s/^\([0-9]*\)4\*/\13*/ s/^\([0-9]*\)5\*/\14*/ s/^\([0-9]*\)6\*/\15*/ s/^\([0-9]*\)7\*/\16*/ s/^\([0-9]*\)8\*/\17*/ s/^\([0-9]*\)9\*/\18*/ s/\*\([0-9*]*\)/*\1+\1/ b mul # get rid of a plus term until 0+x -> x : add /^\+\([0-9+*]*\)=/{ s//\1/ b loop } /^\([0-9*]*\)\+=/{ s//\1/ b loop } /^\([0-9]*\)\+\([0-9*+]*\)\+=/{ s//\2+\1/ b loop } /^\([0-9]*\)0\+\([0-9]*\)\([0-9]\)=/{ s//\1+\2=\3/ b add } /^\([0-9]*\)\([0-9]\)\+\([0-9]*\)0=/{ s//\1+\3=\2/ b add } /^\([0-9]*\)0\+\([0-9*+]*\)\+\([0-9]*\)\([0-9]\)=/{ s//\1+\2+\3=\4/ b add } /^\([0-9]*\)\([0-9]\)\+\([0-9*+]*\)\+\([0-9]*\)0=/{ s//\1+\3+\4=\2/ b add } s/^\([0-9]*\)1\+/\10+/ s/^\([0-9]*\)2\+/\11+/ s/^\([0-9]*\)3\+/\12+/ s/^\([0-9]*\)4\+/\13+/ s/^\([0-9]*\)5\+/\14+/ s/^\([0-9]*\)6\+/\15+/ s/^\([0-9]*\)7\+/\16+/ s/^\([0-9]*\)8\+/\17+/ s/^\([0-9]*\)9\+/\18+/ s/9=\([0-9]*\)$/_=\1/ s/8=\([0-9]*\)$/9=\1/ s/7=\([0-9]*\)$/8=\1/ s/6=\([0-9]*\)$/7=\1/ s/5=\([0-9]*\)$/6=\1/ s/4=\([0-9]*\)$/5=\1/ s/3=\([0-9]*\)$/4=\1/ s/2=\([0-9]*\)$/3=\1/ s/1=\([0-9]*\)$/2=\1/ /_/{ s//_0/ : inc s/9_/_0/ s/8_/9/ s/7_/8/ s/6_/7/ s/5_/6/ s/4_/5/ s/3_/4/ s/2_/3/ s/1_/2/ s/0_/1/ s/\+_/+1/ /_/b inc } b add