Home | History | Annotate | Download | only in testsuite
      1 #!/bin/sed -nf
      2 #  dc.sed - an arbitrary precision RPN calculator
      3 #  Created by Greg Ubben <gsu (at] romulus.ncsc.mil> early 1995, late 1996
      4 #
      5 #  Dedicated to MAC's memory of the IBM 1620 ("CADET") computer.
      6 #  @(#)GSU dc.sed 1.1 06-Mar-1999 [non-explanatory]
      7 #
      8 #  Examples:
      9 #	sqrt(2) to 10 digits:	echo "10k 2vp" | dc.sed
     10 #	20 factorial:		echo "[d1-d1<!*]s! 20l!xp" | dc.sed
     11 #	sin(ln(7)):		echo "s(l(7))" | bc -c /usr/lib/lib.b | dc.sed
     12 #	hex to base 60:		echo "60o16i 6B407.CAFE p" | dc.sed
     13 #	tests most of dc.sed:	echo 16oAk2vp | dc.sed
     14 #
     15 #  To debug or analyze, give the dc Y command as input or add it to
     16 #  embedded dc routines, or add the sed p command to the beginning of
     17 #  the main loop or at various points in the low-level sed routines.
     18 #  If you need to allow [|~] characters in the input, filter this
     19 #  script through "tr '|~' '\36\37'" first (or use dc.pl).
     20 #
     21 #  Not implemented:	! \
     22 #  But implemented:	K Y t # !< !> != fractional-bases
     23 #  SunOS limits:	199/199 commands (though could pack in 10-20 more)
     24 #  Limitations:		scale <= 999; |obase| >= 1; input digits in [0..F]
     25 #  Completed:		1am Feb 4, 1997
     26 
     27 s/^/|P|K0|I10|O10|?~/
     28 
     29 : next
     30 s/|?./|?/
     31 s/|?#[	 -}]*/|?/
     32 /|?!*[lLsS;:<>=]\{0,1\}$/N
     33 /|?!*[-+*/%^<>=]/b binop
     34 /^|.*|?[dpPfQXZvxkiosStT;:]/b binop
     35 /|?[_0-9A-F.]/b number
     36 /|?\[/b string
     37 /|?l/b load
     38 /|?L/b Load
     39 /|?[sS]/b save
     40 /|?c/ s/[^|]*//
     41 /|?d/ s/[^~]*~/&&/
     42 /|?f/ s//&[pSbz0<aLb]dSaxsaLa/
     43 /|?x/ s/\([^~]*~\)\(.*|?x\)~*/\2\1/
     44 /|?[KIO]/ s/.*|\([KIO]\)\([^|]*\).*|?\1/\2~&/
     45 /|?T/ s/\.*0*~/~/
     46 #  a slow, non-stackable array implementation in dc, just for completeness
     47 #  A fast, stackable, associative array implementation could be done in sed
     48 #  (format: {key}value{key}value...), but would be longer, like load & save.
     49 /|?;/ s/|?;\([^{}]\)/|?~[s}s{L{s}q]S}[S}l\1L}1-d0>}s\1L\1l{xS\1]dS{xL}/
     50 /|?:/ s/|?:\([^{}]\)/|?~[s}L{s}L{s}L}s\1q]S}S}S{[L}1-d0>}S}l\1s\1L\1l{xS\1]dS{x/
     51 /|?[ ~	cdfxKIOT]/b next
     52 /|?\n/b next
     53 /|?[pP]/b print
     54 /|?k/ s/^\([0-9]\{1,3\}\)\([.~].*|K\)[^|]*/\2\1/
     55 /|?i/ s/^\(-\{0,1\}[0-9]*\.\{0,1\}[0-9]\{1,\}\)\(~.*|I\)[^|]*/\2\1/
     56 /|?o/ s/^\(-\{0,1\}[1-9][0-9]*\.\{0,1\}[0-9]*\)\(~.*|O\)[^|]*/\2\1/
     57 /|?[kio]/b pop
     58 /|?t/b trunc
     59 /|??/b input
     60 /|?Q/b break
     61 /|?q/b quit
     62 h
     63 /|?[XZz]/b count
     64 /|?v/b sqrt
     65 s/.*|?\([^Y]\).*/\1 is unimplemented/
     66 s/\n/\\n/g
     67 l
     68 g
     69 b next
     70 
     71 : print
     72 /^-\{0,1\}[0-9]*\.\{0,1\}[0-9]\{1,\}~.*|?p/!b Print
     73 /|O10|/b Print
     74 
     75 #  Print a number in a non-decimal output base.  Uses registers a,b,c,d.
     76 #  Handles fractional output bases (O<-1 or O>=1), unlike other dc's.
     77 #  Converts the fraction correctly on negative output bases, unlike
     78 #  UNIX dc.  Also scales the fraction more accurately than UNIX dc.
     79 #
     80 s,|?p,&KSa0kd[[-]Psa0la-]Sad0>a[0P]sad0=a[A*2+]saOtd0>a1-ZSd[[[[ ]P]sclb1\
     81 !=cSbLdlbtZ[[[-]P0lb-sb]sclb0>c1+]sclb0!<c[0P1+dld>c]scdld>cscSdLbP]q]Sb\
     82 [t[1P1-d0<c]scd0<c]ScO_1>bO1!<cO[16]<bOX0<b[[q]sc[dSbdA>c[A]sbdA=c[B]sbd\
     83 B=c[C]sbdC=c[D]sbdD=c[E]sbdE=c[F]sb]xscLbP]~Sd[dtdZOZ+k1O/Tdsb[.5]*[.1]O\
     84 X^*dZkdXK-1+ktsc0kdSb-[Lbdlb*lc+tdSbO*-lb0!=aldx]dsaxLbsb]sad1!>a[[.]POX\
     85 +sb1[SbO*dtdldx-LbO*dZlb!<a]dsax]sadXd0<asbsasaLasbLbscLcsdLdsdLdLak[]pP,
     86 b next
     87 
     88 : Print
     89 /|?p/s/[^~]*/&\
     90 ~&/
     91 s/\(.*|P\)\([^|]*\)/\
     92 \2\1/
     93 s/\([^~]*\)\n\([^~]*\)\(.*|P\)/\1\3\2/
     94 h
     95 s/~.*//
     96 /./{ s/.//; p; }
     97 #  Just s/.//p would work if we knew we were running under the -n option.
     98 #  Using l vs p would kind of do \ continuations, but would break strings.
     99 g
    100 
    101 : pop
    102 s/[^~]*~//
    103 b next
    104 
    105 : load
    106 s/\(.*|?.\)\(.\)/\20~\1/
    107 s/^\(.\)0\(.*|r\1\([^~|]*\)~\)/\1\3\2/
    108 s/.//
    109 b next
    110 
    111 : Load
    112 s/\(.*|?.\)\(.\)/\2\1/
    113 s/^\(.\)\(.*|r\1\)\([^~|]*~\)/|\3\2/
    114 /^|/!i\
    115 register empty
    116 s/.//
    117 b next
    118 
    119 : save
    120 s/\(.*|?.\)\(.\)/\2\1/
    121 /^\(.\).*|r\1/ !s/\(.\).*|/&r\1|/
    122 /|?S/ s/\(.\).*|r\1/&~/
    123 s/\(.\)\([^~]*~\)\(.*|r\1\)[^~|]*~\{0,1\}/\3\2/
    124 b next
    125 
    126 : quit
    127 t quit
    128 s/|?[^~]*~[^~]*~/|?q/
    129 t next
    130 #  Really should be using the -n option to avoid printing a final newline.
    131 s/.*|P\([^|]*\).*/\1/
    132 q
    133 
    134 : break
    135 s/[0-9]*/&;987654321009;/
    136 : break1
    137 s/^\([^;]*\)\([1-9]\)\(0*\)\([^1]*\2\(.\)[^;]*\3\(9*\).*|?.\)[^~]*~/\1\5\6\4/
    138 t break1
    139 b pop
    140 
    141 : input
    142 N
    143 s/|??\(.*\)\(\n.*\)/|?\2~\1/
    144 b next
    145 
    146 : count
    147 /|?Z/ s/~.*//
    148 /^-\{0,1\}[0-9]*\.\{0,1\}[0-9]\{1,\}$/ s/[-.0]*\([^.]*\)\.*/\1/
    149 /|?X/ s/-*[0-9A-F]*\.*\([0-9A-F]*\).*/\1/
    150 s/|.*//
    151 /~/ s/[^~]//g
    152 
    153 s/./a/g
    154 : count1
    155 	s/a\{10\}/b/g
    156 	s/b*a*/&a9876543210;/
    157 	s/a.\{9\}\(.\).*;/\1/
    158 	y/b/a/
    159 /a/b count1
    160 G
    161 /|?z/ s/\n/&~/
    162 s/\n[^~]*//
    163 b next
    164 
    165 : trunc
    166 #  for efficiency, doesn't pad with 0s, so 10k 2 5/ returns just .40
    167 #  The X* here and in a couple other places works around a SunOS 4.x sed bug.
    168 s/\([^.~]*\.*\)\(.*|K\([^|]*\)\)/\3;9876543210009909:\1,\2/
    169 : trunc1
    170 	s/^\([^;]*\)\([1-9]\)\(0*\)\([^1]*\2\(.\)[^:]*X*\3\(9*\)[^,]*\),\([0-9]\)/\1\5\6\4\7,/
    171 t trunc1
    172 s/[^:]*:\([^,]*\)[^~]*/\1/
    173 b normal
    174 
    175 : number
    176 s/\(.*|?\)\(_\{0,1\}[0-9A-F]*\.\{0,1\}[0-9A-F]*\)/\2~\1~/
    177 s/^_/-/
    178 /^[^A-F~]*~.*|I10|/b normal
    179 /^[-0.]*~/b normal
    180 s:\([^.~]*\)\.*\([^~]*\):[Ilb^lbk/,\1\2~0A1B2C3D4E5F1=11223344556677889900;.\2:
    181 : digit
    182     s/^\([^,]*\),\(-*\)\([0-F]\)\([^;]*\(.\)\3[^1;]*\(1*\)\)/I*+\1\2\6\5~,\2\4/
    183 t digit
    184 s:...\([^/]*.\)\([^,]*\)[^.]*\(.*|?.\):\2\3KSb[99]k\1]SaSaXSbLalb0<aLakLbktLbk:
    185 b next
    186 
    187 : string
    188 /|?[^]]*$/N
    189 s/\(|?[^]]*\)\[\([^]]*\)]/\1|{\2|}/
    190 /|?\[/b string
    191 s/\(.*|?\)|{\(.*\)|}/\2~\1[/
    192 s/|{/[/g
    193 s/|}/]/g
    194 b next
    195 
    196 : binop
    197 /^[^~|]*~[^|]/ !i\
    198 stack empty
    199 //!b next
    200 /^-\{0,1\}[0-9]*\.\{0,1\}[0-9]\{1,\}~/ !s/[^~]*\(.*|?!*[^!=<>]\)/0\1/
    201 /^[^~]*~-\{0,1\}[0-9]*\.\{0,1\}[0-9]\{1,\}~/ !s/~[^~]*\(.*|?!*[^!=<>]\)/~0\1/
    202 h
    203 /|?\*/b mul
    204 /|?\//b div
    205 /|?%/b rem
    206 /|?^/b exp
    207 
    208 /|?[+-]/ s/^\(-*\)\([^~]*~\)\(-*\)\([^~]*~\).*|?\(-\{0,1\}\).*/\2\4s\3o\1\3\5/
    209 s/\([^.~]*\)\([^~]*~[^.~]*\)\(.*\)/<\1,\2,\3|=-~.0,123456789<></
    210 /^<\([^,]*,[^~]*\)\.*0*~\1\.*0*~/ s/</=/
    211 : cmp1
    212 	s/^\(<[^,]*\)\([0-9]\),\([^,]*\)\([0-9]\),/\1,\2\3,\4/
    213 t cmp1
    214 /^<\([^~]*\)\([^~]\)[^~]*~\1\(.\).*|=.*\3.*\2/ s/</>/
    215 /|?/{
    216 	s/^\([<>]\)\(-[^~]*~-.*\1\)\(.\)/\3\2/
    217 	s/^\(.\)\(.*|?!*\)\1/\2!\1/
    218 	s/|?![^!]\(.\)/&l\1x/
    219 	s/[^~]*~[^~]*~\(.*|?\)!*.\(.*\)|=.*/\1\2/
    220 	b next
    221 }
    222 s/\(-*\)\1|=.*/;9876543210;9876543210/
    223 /o-/ s/;9876543210/;0123456789/
    224 s/^>\([^~]*~\)\([^~]*~\)s\(-*\)\(-*o\3\(-*\)\)/>\2\1s\5\4/
    225 
    226 s/,\([0-9]*\)\.*\([^,]*\),\([0-9]*\)\.*\([0-9]*\)/\1,\2\3.,\4;0/
    227 : right1
    228 	s/,\([0-9]\)\([^,]*\),;*\([0-9]\)\([0-9]*\);*0*/\1,\2\3,\4;0/
    229 t right1
    230 s/.\([^,]*\),~\(.*\);0~s\(-*\)o-*/\1~\30\2~/
    231 
    232 : addsub1
    233 	s/\(.\{0,1\}\)\(~[^,]*\)\([0-9]\)\(\.*\),\([^;]*\)\(;\([^;]*\(\3[^;]*\)\).*X*\1\(.*\)\)/\2,\4\5\9\8\7\6/
    234 	s/,\([^~]*~\).\{10\}\(.\)[^;]\{0,9\}\([^;]\{0,1\}\)[^;]*/,\2\1\3/
    235 #	  could be done in one s/// if we could have >9 back-refs...
    236 /^~.*~;/!b addsub1
    237 
    238 : endbin
    239 s/.\([^,]*\),\([0-9.]*\).*/\1\2/
    240 G
    241 s/\n[^~]*~[^~]*//
    242 
    243 : normal
    244 s/^\(-*\)0*\([0-9.]*[0-9]\)[^~]*/\1\2/
    245 s/^[^1-9~]*~/0~/
    246 b next
    247 
    248 : mul
    249 s/\(-*\)\([0-9]*\)\.*\([0-9]*\)~\(-*\)\([0-9]*\)\.*\([0-9]*\).*|K\([^|]*\).*/\1\4\2\5.!\3\6,|\2<\3~\5>\6:\7;9876543210009909/
    250 
    251 : mul1
    252     s/![0-9]\([^<]*\)<\([0-9]\{0,1\}\)\([^>]*\)>\([0-9]\{0,1\}\)/0!\1\2<\3\4>/
    253     /![0-9]/ s/\(:[^;]*\)\([1-9]\)\(0*\)\([^0]*\2\(.\).*X*\3\(9*\)\)/\1\5\6\4/
    254 /<~[^>]*>:0*;/!t mul1
    255 
    256 s/\(-*\)\1\([^>]*\).*/;\2^>:9876543210aaaaaaaaa/
    257 
    258 : mul2
    259     s/\([0-9]~*\)^/^\1/
    260     s/<\([0-9]*\)\(.*[~^]\)\([0-9]*\)>/\1<\2>\3/
    261 
    262     : mul3
    263 	s/>\([0-9]\)\(.*\1.\{9\}\(a*\)\)/\1>\2;9\38\37\36\35\34\33\32\31\30/
    264 	s/\(;[^<]*\)\([0-9]\)<\([^;]*\).*\2[0-9]*\(.*\)/\4\1<\2\3/
    265 	s/a[0-9]/a/g
    266 	s/a\{10\}/b/g
    267 	s/b\{10\}/c/g
    268     /|0*[1-9][^>]*>0*[1-9]/b mul3
    269 
    270     s/;/a9876543210;/
    271     s/a.\{9\}\(.\)[^;]*\([^,]*\)[0-9]\([.!]*\),/\2,\1\3/
    272     y/cb/ba/
    273 /|<^/!b mul2
    274 b endbin
    275 
    276 : div
    277 #  CDDET
    278 /^[-.0]*[1-9]/ !i\
    279 divide by 0
    280 //!b pop
    281 s/\(-*\)\([0-9]*\)\.*\([^~]*~-*\)\([0-9]*\)\.*\([^~]*\)/\2.\3\1;0\4.\5;0/
    282 : div1
    283 	s/^\.0\([^.]*\)\.;*\([0-9]\)\([0-9]*\);*0*/.\1\2.\3;0/
    284 	s/^\([^.]*\)\([0-9]\)\.\([^;]*;\)0*\([0-9]*\)\([0-9]\)\./\1.\2\30\4.\5/
    285 t div1
    286 s/~\(-*\)\1\(-*\);0*\([^;]*[0-9]\)[^~]*/~123456789743222111~\2\3/
    287 s/\(.\(.\)[^~]*\)[^9]*\2.\{8\}\(.\)[^~]*/\3~\1/
    288 s,|?.,&SaSadSaKdlaZ+LaX-1+[sb1]Sbd1>bkLatsbLa[dSa2lbla*-*dLa!=a]dSaxsakLasbLb*t,
    289 b next
    290 
    291 : rem
    292 s,|?%,&Sadla/LaKSa[999]k*Lak-,
    293 b next
    294 
    295 : exp
    296 #  This decimal method is just a little faster than the binary method done
    297 #  totally in dc:  1LaKLb [kdSb*LbK]Sb [[.5]*d0ktdSa<bkd*KLad1<a]Sa d1<a kk*
    298 /^[^~]*\./i\
    299 fraction in exponent ignored
    300 s,[^-0-9].*,;9d**dd*8*d*d7dd**d*6d**d5d*d*4*d3d*2lbd**1lb*0,
    301 : exp1
    302 	s/\([0-9]\);\(.*\1\([d*]*\)[^l]*\([^*]*\)\(\**\)\)/;dd*d**d*\4\3\5\2/
    303 t exp1
    304 G
    305 s,-*.\{9\}\([^9]*\)[^0]*0.\(.*|?.\),\2~saSaKdsaLb0kLbkK*+k1\1LaktsbkLax,
    306 s,|?.,&SadSbdXSaZla-SbKLaLadSb[0Lb-d1lb-*d+K+0kkSb[1Lb/]q]Sa0>a[dk]sadK<a[Lb],
    307 b next
    308 
    309 : sqrt
    310 #  first square root using sed:  8k2v at 1:30am Dec 17, 1996
    311 /^-/i\
    312 square root of negative number
    313 /^[-0]/b next
    314 s/~.*//
    315 /^\./ s/0\([0-9]\)/\1/g
    316 /^\./ !s/[0-9][0-9]/7/g
    317 G
    318 s/\n/~/
    319 s,|?.,&K1+k KSbSb[dk]SadXdK<asadlb/lb+[.5]*[sbdlb/lb+[.5]*dlb>a]dsaxsasaLbsaLatLbk K1-kt,
    320 b next
    321 
    322 #  END OF GSU dc.sed
    323