source: trunk/third/sed/dc.sed @ 17271

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