root/trunk/pst-map3d/pst-algparser.pro

Revision 5, 28.2 kB (checked in by jms, 2 years ago)

Déplacement des fichiers de Manuel dans le répertoire pst-map3d.

Line 
1% $Id: pst-algparser.pro 7 2007-12-29 22:21:13Z herbert $
2%
3% PostScript prologue for PSTricks algorithm parser
4% Version 0.01, 2008/01/01
5% For distribution and copyright, see pstricks.tex.   hv@pstricks.de
6%
7%-----------------------------------------------------------------------------%
8/AlgParser { tx@AlgToPs begin AlgToPs end } def  % Dominique Rodriguez
9%
10/tx@CoreAnalyzerDict 100 dict def tx@CoreAnalyzerDict begin
11%
12% PS ANALYZER FOR ALGEBRAIC EXPRESSION V1.12
13% E->T|E+T
14% T->FS|T*FS
15% FS -> F | +FS | -FS
16% F->P|F^SF
17% P->(E)|literal
18% literal->number|var|var[E]|func(params)
19% params->E|E,param
20% number->TOBEFINISHED
21%
22%% E expression, T term, SF signed factor, F factor, P power
23%
24%% parser
25%
26%% str
27%
28%% C->E<condition_operators>E
29%% STR index -> STR index+lenExpr
30/AnalyzeCond { AnalyzeExpr ReadCondOp AnalyzeExpr EvalCondOp  } def
31%
32%% analyze Expression List (separator , or | )
33%% STR index -> STR index+lenExpr
34%% /AnalyzeListOfE {
35%%   { NextNonBlankChar pop AnalyzeExpr%%dup Strlen eq { exit } if NextNonBlankChar
36%%     NextNonBlankChar dup 0 eq { pop exit } if
37%%     dup 44 ne 1 index 124 ne and { dup 41 ne { PROBLEMCONTACTBILLOU } { pop exit } ifelse } if
38%%     pop NextNonBlankChar dup 0 eq { exit } if 124 ne { PROBLEMCONTACTBILLOU } if 1 add NextNonBlankChar 0 eq {toto} if } loop
39%%   AnalyzeListOfEPostHook
40%% } def
41/AnalyzeListOfE {
42  /NotFirst false def
43  { NextNonBlankChar pop AnalyzeExpr
44    NotFirst { EvalListOfExpr } { /NotFirst true def } ifelse
45    dup Strlen eq { exit } if NextNonBlankChar
46    dup 44 ne 1 index 124 ne and
47    { dup 41 ne { PROBLEMCONTACTBILLOU } { pop exit } ifelse }
48    if  pop 1 add } loop
49  AnalyzeListOfEPostHook
50} def
51%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
52%% E->T|E+T
53%% STR index -> STR index+lenExpr
54/AnalyzeExpr {
55  AnalyzePreHook AnalyzeTerm IsEndingExpr
56  { dup 0 ne { 32 eq { NextNonBlankChar } if } { pop } ifelse }
57  { { RollOp 1 add NextNonBlankChar pop AnalyzeTerm PreEvalHook EvalAddSub IsEndingExpr { pop exit } if } loop }
58  ifelse
59  AnalyzePostHook
60} def
61%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
62%% T->FS|T*FS
63%% STR index
64/AnalyzeTerm {
65  AnalyzePreHook AnalyzeSignedFactor IsEndingTerm
66  { dup 0 ne { 32 eq { NextNonBlankChar } if } { pop } ifelse }
67  { { RollOp 1 add NextNonBlankChar pop AnalyzeSignedFactor PreEvalHook EvalMulDiv IsEndingTerm { pop exit } if} loop }
68  ifelse
69  AnalyzePostHook
70} def
71%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
72%% FS -> F | +FS | -FS
73%% STR index
74/AnalyzeSignedFactor {
75  AnalyzePreHook 2 copy get dup IsUnaryOp
76  { RollOp 1 add NextNonBlankChar pop AnalyzeSignedFactor EvalUnaryOp }
77  { pop AnalyzeFactor }
78  ifelse AnalyzePostHook
79} def
80%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
81%% F->P|F^P
82%% STR index
83/AnalyzeFactor {
84  AnalyzePreHook AnalyzePower IsEndingFactor
85  { dup 0 ne { 32 eq { NextNonBlankChar } if } { pop } ifelse }
86  { { RollOp 1 add NextNonBlankChar pop AnalyzePower PreEvalHook EvalPower IsEndingFactor { pop exit } if} loop }
87  ifelse  AnalyzePostHook
88} def
89%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
90%% P->(E)|literal
91%% STR index
92/AnalyzePower {
93  %% depending of first char either a number, or a literal
94  2 copy get dup 40 eq%%an open par
95  { pop 1 add NextNonBlankChar pop AnalyzeExpr 1 add NextNonBlankChar pop }
96  { AnalyzeLiteral }
97  ifelse
98} def
99%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
100%% STR index STR[index] -> STR index
101%/AnalyzeLiteral { IsNumber { EvalNumber } { EvalLiteral } ifelse } def
102/AnalyzeLiteral { dup IsUnaryOp exch IsNumber or { EvalNumber } { EvalLiteral } ifelse } def%%dr 09102006
103%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
104%% recognize + or -
105%% chr -> T/F
106/IsUnaryOp { dup 43 eq exch 45 eq or } bind def
107%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
108%% a number can contain only : 0123456789.
109%% chr -> T/F
110/IsNumber { dup 48 ge exch dup 57 le 3 -1 roll and exch 46 eq or } bind def
111%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
112%% STR index -> STR index number
113%% a number can be of the form [0-9]*.[0-9]*\([eE][+-]?[0-9]+\)?
114%% STR index -> STR index' number
115/ReadNumber {
116  exch dup 3 -1 roll dup 3 1 roll
117  %%read mantissa
118  { 1 add  2 copy dup Strlen eq { pop pop 0 exit } if get dup IsNumber not { exit } if pop } loop
119  dup 101 eq exch 69 eq or
120  %%% there is a "e" or "E" -> read exponant
121  { 1 add 2 copy get dup IsUnaryOp
122    { pop 1 add 2 copy get } if
123    { IsNumber not { exit } if 1 add 2 copy get } loop }
124  if
125  dup 4 1 roll
126  3 -1 roll exch 1 index sub getinterval
127} def
128%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
129%% a number can contain only : 0123456789.
130%% chr -> T/F
131/IsCondOp { dup 30 eq exch dup 60 ge exch 62 le and or } bind def
132%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
133%% STR index -> STR index number
134%% a number can be of the form [0-9]*.[0-9]*\([eE][+-]?[0-9]+\)?
135%% STR index -> STR index' number
136/ReadCondOp {
137  NextNonBlankChar 1 index 4 1 roll
138  { IsCondOp not { exit } if 1 add  2 copy get } loop
139  2 copy 5 -1 roll
140  exch 1 index sub getinterval 3 1 roll
141} def
142%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
143%% a literal can contain only : 0123456789.
144%% chr -> T/F
145/IsLiteral {%
146  dup 48 ge exch dup  57 le 3 -1 roll and exch
147  dup 65 ge exch dup  90 le 3 -1 roll and 3 -1 roll or exch
148  dup 97 ge exch     122 le and or } bind def
149%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
150%% a literal can be of the form [a-zA-Z][a-zA-Z0-9]*\(\((Expression)\)|\(\[Expression\]\)\)?
151%% STR index -> literal STR index' nextchr
152/ReadLiteral {
153  exch dup 3 -1 roll dup 3 1 roll
154  %%read literal core
155  { 2 copy dup Strlen eq { pop pop 0 exit } if get dup IsLiteral not { exit } if pop 1 add } loop
156  4 1 roll dup 5 1 roll 3 -1 roll exch 1 index sub getinterval 4 1 roll
157} def
158%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
159%% expr is ended by end of str or a clpar
160%% STR index -> STR index STR[index] T/F
161/IsEndingExpr {%
162  2 copy dup Strlen eq
163  %% if end of str is reached -> end !
164  { pop pop 0 true }
165  %% ending chr -> clpar, comma, |, <, >, =, !,
166  {get dup  dup  41 eq
167       exch dup 124 eq
168       exch dup  93 eq
169       exch dup  44 eq
170       exch dup  30 eq
171       exch dup  60 ge exch 62 le and or or or or or}
172  ifelse } def
173%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
174%% expr is ended by end of str or a +-
175%% STR index -> STR index STR[index] T/F
176/IsEndingTerm { IsEndingExpr { true } { dup dup 43 eq exch 45 eq or } ifelse } def
177%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
178%% expr is ended by end of str or */
179%% STR index -> STR index STR[index] T/F
180/IsEndingFactor { IsEndingTerm { true } { dup dup 42 eq exch 47 eq or } ifelse } def
181%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
182%% expr is ended by end of str or ^
183%% STR index -> STR index STR[index] T/F
184/IsEndingPower { IsEndingFactor { true } { dup 94 eq } ifelse } def
185%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
186%% STR index -> STR index STR[index]
187/NextNonBlankChar { { dup Strlen eq { 0 exit } if 2 copy get dup neBlkChar { exit } if pop 1 add } loop } bind def
188/neBlkChar { dup 32 ne exch dup 10 ne exch 9 ne and and } bind def
189%%%%%%%%%%%%%%%%%%%%%%%%
190%% DEBUG
191/BRK {false} def
192/BRKtrue {/BRK true def} def
193/BRKStop {BRK {BRKtoto} if } def
194/BRKEvalStop {BRK exch if } def
195/BRKBRK2true {BRK {BRK2true} if } def
196/BRK2 {false} def
197/BRK2true {/BRK2 true def} def
198/BRK2Stop {BRK2 {BRK2toto} if } def/BRK {false} def
199end
200%
201%-------------------------------------------------------------------------------%
202%
203/tx@AlgToPs 12 dict def tx@AlgToPs begin
204%
205%% algExpr -> PSVector
206/AlgToPs { tx@CoreAnalyzerDict begin InitParser AnalyzeListOfE pop pop EndingSequence end } def
207/EndingSequence { ExpressionVector aload length /end cvx exch 1 add array astore } def
208/InitParser { /ExpressionVector [ /tx@AddMathFunc cvx /begin cvx ] def dup length /Strlen exch def 0 } def
209/Strlen 0 def
210/EvalListOfExpr {} def%
211/EvalNumber {%
212    ReadNumber  cvr /ExpressionVector ExpressionVector aload length dup 3 add -1 roll cvx
213    exch 1 add array astore def NextNonBlankChar pop } def
214/EvalAddSub {%
215  /ExpressionVector ExpressionVector aload length dup 5 add -1 roll
216  43 eq { /add } { /sub } ifelse cvx exch 1 add array astore def
217} def
218/EvalMulDiv {%
219  /ExpressionVector ExpressionVector aload length dup 5 add -1 roll
220  42 eq { /mul } { /div } ifelse cvx exch 1 add array astore def
221} def
222/EvalPower {%
223  /ExpressionVector ExpressionVector aload length dup 5 add -1 roll
224  pop /exp cvx exch 1 add array astore def
225} def
226/EvalLiteral {%
227  ReadLiteral
228  dup 40 eq%%% there is an open par -> function call
229  { pop 2 index
230    dup (Sum) eq { EvalSum }
231    { dup (IfTE) eq { EvalCond }
232      { dup (Derive) eq { pop EvalDerive }
233        { pop 1 add NextNonBlankChar pop AnalyzeListOfE 2 index TrigoFunc
234          /ExpressionVector ExpressionVector aload length dup 5 add -1 roll cvn cvx
235          exch 1 add array astore def 1 add NextNonBlankChar pop } ifelse } ifelse} ifelse }
236  { /ExpressionVector ExpressionVector aload length dup 6 add -1 roll cvn cvx exch 1 add array astore def
237    dup 91 eq%%% there is an open bracket -> vector element
238    { pop 1 add NextNonBlankChar pop AnalyzeExpr
239      /ExpressionVector ExpressionVector aload length /cvi cvx exch /get cvx exch 2 add array astore def 1 add }
240    { pop NextNonBlankChar pop }
241    ifelse}
242  ifelse
243} def
244%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
245%% the derive function : Derive(n,f(x))
246%% firstparindex lastparindex ->
247/EvalDerive {
248  %% manage the function descripiton
249  1 add ReadNumber 3 1 roll NextNonBlankChar
250  44 ne { ANALYZER_ERROR_missing_second_comma_in_Sum } if
251  1 add NextNonBlankChar pop
252  3 -1 roll cvi
253  dup 0 eq
254  { pop AnalyzeExpr 3 -1 roll pop 1 add }
255  { 1 sub 3 1 roll (x)  exch tx@Derive begin DeriveIndexed end 4 -1 roll
256    { (x) tx@Derive begin Derive end } repeat
257    ExpressionVector exch /ExpressionVector [] def
258    AlgToPs aload length
259    /ExpressionVector 1 index 3 add -1 roll aload length dup 3 add -1 roll  /l2 exch def /l1 exch def
260    l1 l2 add 1 add l2 neg roll l1 l2 add array astore def 3 -1 roll pop 1 add
261    1 index length /Strlen exch def } ifelse
262} def
263/EvalSum {%
264  pop 1 add NextNonBlankChar pop
265  %% read the variable name
266  ReadLiteral pop NextNonBlankChar
267  44 ne { ANALYZER_ERROR_missing_first_comma_in_Sum } if
268  %% read the initial value
269  1 add NextNonBlankChar pop ReadNumber cvi 3 1 roll
270  2 copy get 44 ne { ANALYZER_ERROR_missing_second_comma_in_Sum } if
271  %% read the increment value
272  1 add NextNonBlankChar pop ReadNumber cvi 3 1 roll
273  2 copy get 44 ne { ANALYZER_ERROR_missing_second_comma_in_Sum } if
274  %% read the limit value
275  1 add NextNonBlankChar pop ReadNumber cvi 3 1 roll
276  2 copy get 44 ne { ANALYZER_ERROR_missing_second_comma_in_Sum } if
277  /ExpressionVector ExpressionVector aload length dup 7 add -3 roll 0 4 1 roll
278  5 -1 roll 4 add array astore def
279  %% keep ExpressionVector for later and create a new one for internal Sum computation
280  ExpressionVector 3 1 roll /ExpressionVector [ 6 -1 roll cvn /exch cvx /def cvx ] def
281  1 add NextNonBlankChar pop AnalyzeExpr
282  %% add each term
283  /ExpressionVector ExpressionVector aload length 1 add /add cvx exch array astore def
284  /ExpressionVector 4 -1 roll aload length ExpressionVector cvx /for cvx 3 -1 roll 2 add
285  array astore def 3 -1 roll pop 1 add
286} def
287%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
288%% Convert to radians if trigo function call
289%% (name) ->
290/TrigoFunc {
291  dup (cos) eq 1 index (sin) eq or exch (tan) eq or
292  { /ExpressionVector ExpressionVector aload length Pi /div cvx 180 /mul cvx 5 -1 roll 4 add
293    array astore def
294  } if
295} def
296/EvalCond {%
297  pop 1 add AnalyzeCond NextNonBlankChar
298  44 ne { ANALYZER_ERROR_missing_first_comma_in_IfTE } if
299  ExpressionVector 3 1 roll /ExpressionVector [] def
300  1 add AnalyzeExpr ExpressionVector 3 1 roll /ExpressionVector [] def
301  NextNonBlankChar 44 ne { ANALYZER_ERROR_missing_second_comma_in_IfTE } if
302  1 add AnalyzeExpr
303  NextNonBlankChar 41 ne { ANALYZER_ERROR_missing_ending parenthesis_in_IfTE } if
304  ExpressionVector
305  /ExpressionVector 6 -1 roll aload length dup
306  6 add -1 roll cvx exch dup 4 add -1 roll cvx /ifelse cvx 3 -1 roll 3 add array astore def
307  1 add 3 -1 roll pop
308} def
309%% CondOp STR index
310/EvalCondOp {%
311  3 -1 roll
312  dup (=) eq  { /eq } {%
313  dup (<) eq  { /lt } {%
314  dup (>) eq  { /gt } {%
315  dup (>=) eq { /ge } {%
316  dup (<=) eq { /ge } {%
317  dup (!=) eq { /ne } { ERROR_non_valid_conditional_operator }
318  ifelse } ifelse } ifelse } ifelse } ifelse } ifelse
319  cvx exch pop
320  /ExpressionVector ExpressionVector aload length dup 3 add -1 roll exch 1 add array astore def } def
321/EvalUnaryOp {
322  3 -1 roll 45 eq { /ExpressionVector ExpressionVector aload length /neg cvx exch 1 add array astore def } if
323} def
324%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
325%% H O O K S
326/AnalyzePreHook {} bind def
327/PreEvalHook {} bind def
328/AnalyzeListOfEPostHook {} bind def
329/AnalyzePostHook {} def
330/RollOp { 3 1 roll } bind def
331end   %tx@CoreAnalyzerDict
332%
333%--------------------------------------------------------------------%
334%
335/tx@Derive 41 dict def tx@Derive begin
336%%increase ^^ for each function added
337%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
338%% algExpr variable -> PSVector
339/Derive {%
340  10240 string 3 1 roll 0 3 1 roll
341  /Variable exch def
342  tx@CoreAnalyzerDict begin InitParser AnalyzeListOfE end
343} def
344/Strlen 0 def
345/InitParser { dup length /Strlen exch def 0 } def
346%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
347%% algExpr variable index -> PSVector
348/DeriveIndexed {%
349  3 1 roll 10240 string 3 1 roll 0 3 1 roll
350  /Variable exch def
351  tx@CoreAnalyzerDict begin InitParser pop 4 -1 roll AnalyzeExpr 4 -2 roll pop pop 4 -2 roll exch pop end
352} def
353%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
354%% (u,v)'=-(u',v')
355/EvalListOfExpr {%
356  4 2 roll 2 copy 9 -1 roll dup length 4 1 roll putinterval add AddPipe
357           2 copy 7 -1 roll dup length 4 1 roll putinterval add
358  6 -2 roll pop pop
359  2 copy pop 0 6 2 roll GetIntervalNewStr 5 1 roll 2 copy 0 exch getinterval 6 1 roll } def
360%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
361%% (-u)'=-(u')
362/EvalUnaryOp {
363  4 -2 roll 4 index (0) eq
364  { (0) StrConcat 7 -1 roll pop }
365  { 7 -1 roll 45 eq
366    { AddSub AddOpPar true } { false } ifelse
367    3 1 roll 5 index StrConcat 3 -1 roll { AddClPar } if } ifelse
368  2 copy pop 0 6 2 roll GetIntervalNewStr
369  7 -2 roll pop pop 2 index 6 index dup 4 index exch sub getinterval exch 6 2 roll
370} def
371%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
372%% (number)'=0
373/EvalNumber { ReadNumber (0) 6 2 roll } def
374%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
375%% (u+v)'=u'+v'
376/EvalAddSub {%
377  7 index dup (0) eq
378  { pop true }%% du=0 nothing added
379  { dup length exch 5 index 5 index 3 -1 roll putinterval 4 -1 roll add 3 1 roll false }
380  ifelse
381  5 index dup (0) eq
382  { pop { (0) } { 4 -2 roll 2 copy pop 0  6 2 roll GetIntervalNewStr } ifelse }%%dv=0
383  { exch
384    { 5 -2 roll 7 index 45 eq { AddSub } if false } %%nothing yet added
385    { 5 -2 roll 7 index 43 eq%%something yet added
386      { AddAdd false } { AddSub AddOpPar true } ifelse }
387    ifelse 11 1 roll
388    3 -1 roll StrConcat 10 -1 roll { AddClPar } if
389    2 copy pop 0 6 2 roll GetIntervalNewStr }
390  ifelse
391  mark 11 -5 roll cleartomark 2 index 6 index dup 4 index exch sub getinterval exch 6 2 roll
392} def
393%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
394%% (u*v)' or (u/v)'
395/EvalMulDiv { 6 index 42 eq {EvalMul} {EvalDiv} ifelse } def
396%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
397%% (u*v)'=u'*v+u*v'
398/EvalMul {%
399  4 -2 roll 7 index dup (0) eq
400  { pop false }%%du=0
401  { (1) eq%%du=1
402    { false }
403    { AddOpPar 7 index StrConcat AddClPar AddMul AddOpPar true } ifelse
404    3 1 roll 6 index StrConcat 3 -1 roll { AddClPar } if
405    true }%%du!=0
406  ifelse
407  5 1 roll 5 index (0) eq
408  { 5 -1 roll not { (0) StrConcat } if }%%dv=0
409  { 5 -1 roll { AddAdd } if
410    4 index (1) eq
411    { 8 index StrConcat }
412    { AddOpPar 8 index StrConcat AddClPar AddMul AddOpPar 4 index StrConcat AddClPar }
413    ifelse
414  }%%dv!=0
415  ifelse
416  2 copy pop 0 6 2 roll GetIntervalNewStr
417  mark 11 -5 roll cleartomark 2 index 6 index dup 4 index exch sub getinterval exch 6 2 roll
418} def
419%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
420%% (u/v)'=(u'*v-u*v')/v^2
421/EvalDiv {%
422  4 -2 roll
423  4 index (0) eq%%dv=0 -> u'/v
424  { 7 index (0) eq { (0) StrConcat } { AddOpPar 7 index StrConcat AddClPar AddDiv 5 index StrConcat } ifelse }
425  { 7 index dup (0) eq
426    { pop }%%du=0
427    { (1) eq%%du=1
428      { false }
429      { AddOpPar 7 index StrConcat AddClPar AddMul AddOpPar true } ifelse
430      3 1 roll 6 index StrConcat 3 -1 roll { AddClPar } if}%%du!=0
431    ifelse
432      AddSub
433      4 index (1) eq
434      { 8 index StrConcat }
435      { AddOpPar 8 index StrConcat AddClPar AddMul AddOpPar 4 index StrConcat AddClPar }
436      ifelse
437    %}%%dv!=0
438    2 copy GetIntervalNewStr 3 1 roll pop 0 AddOpPar 3 -1 roll StrConcat AddClPar
439    AddDiv AddOpPar 5 index StrConcat AddClPar 2 copy (^2) putinterval 2 add }
440  ifelse
441  2 copy pop 0 6 2 roll GetIntervalNewStr
442  mark 11 -5 roll cleartomark 2 index 6 index dup 4 index exch sub getinterval exch 6 2 roll
443} def
444%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
445%% str1 index str2 -> str1 index
446/StrConcat { dup length 4 2 roll 2 copy 6 -1 roll putinterval 3 -1 roll add } bind def
447/GetIntervalNewStr { 0 exch getinterval dup length string copy } bind def
448%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
449%% (u^v)'=(u^v)'=u'vu^(v-1)+v'u^(v)ln(u)
450/EvalPower {%
451  4 -2 roll 7 index (0) eq
452  {%%if du=0 then (u^v)'=v'ln(u)u^v
453    4 index (0) eq
454    { (0) StrConcat }%%if dv=0 then (u^v)'=0
455    { 4 index (1) ne { AddOpPar 4 index StrConcat (\)*) StrConcat } if
456      8 index (e) ne { (ln\() StrConcat 8 index StrConcat (\)*) StrConcat } if
457      AddOpPar 8 index StrConcat (\)^\() StrConcat 5 index StrConcat AddClPar } ifelse
458  }
459  {%%du!=0
460    4 index (0) eq
461    {%%if dv=0 then (u^v)'=vu'u^(v-1)
462      5 index dup IsStrNumber
463      { dup (0) eq
464        { StrConcat }
465        { dup dup (1) eq exch (1.0) eq or
466          { StrConcat  }
467          { StrConcat
468            7 index dup (1) ne exch (1.0) ne and%%%dr 09102006 insert du if <> 1
469            { (*\() StrConcat 7 index StrConcat (\)) StrConcat } if%%%dr 09102006
470            (*\() StrConcat 8 index StrConcat (\)) StrConcat
471            5 index  dup dup (2) eq exch (2.0) eq or
472            { pop } { cvr 1 sub 20 string cvs 3 1 roll (^) StrConcat 3 -1 roll StrConcat } ifelse } ifelse } ifelse }
473      { pop AddOpPar 5 index StrConcat (\)*\() StrConcat 8 index StrConcat (\)^\() StrConcat
474        5 index StrConcat (-1\)) StrConcat } ifelse
475    }
476    {%%if dv!=0 and du!=0 then (u^v)'=u'vu^(v-1)+v'u^(v)ln(u)
477      7 index (1) ne { AddOpPar 7 index StrConcat (\)*) StrConcat } if
478      AddOpPar 5 index StrConcat (\)*\() StrConcat
479      8 index StrConcat (\)^\() StrConcat
480      5 index StrConcat (-1\)+\() StrConcat
481      4 index (1) ne { 4 index StrConcat (\)*\() StrConcat } if
482      8 index StrConcat (\)^\() StrConcat
483      5 index StrConcat (\)*ln\() StrConcat
484      8 index StrConcat AddClPar
485    } ifelse
486  } ifelse
487  2 copy pop 0 6 2 roll GetIntervalNewStr
488  mark 11 -5 roll cleartomark 2 index 6 index dup 4 index exch sub getinterval exch 6 2 roll
489} def
490%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
491%% str -> true/false
492/IsStrNumber {%
493  true exch
494  { dup 48 lt exch dup 57 gt 3 -1 roll or
495    exch dup 46 ne%%.
496    exch dup 43 ne%%+
497    exch 45 ne%%-
498    and and and { pop false } if } forall
499} def
500%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
501%% literal switch -> func call, vector, variables
502/EvalLiteral {%
503  ReadLiteral dup 40 eq%%% there is an open par -> function call
504  { pop (EvalFunc_             ) 9 4 index StrConcat 0 exch getinterval cvn cvx exec }
505  { dup 91 eq%%% there is an open bracket -> vector element
506    { ERROR_vector_not_yet_implemented }
507    { pop EvalVariable }
508    ifelse }
509  ifelse
510} def
511%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
512%% first last parpos Expr[first:parpos-1] ->
513/EvalVariable { 2 index Variable eq { (1) } { (0) } ifelse 4 -1 roll exch 6 2 roll } def
514%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
515%% (f(u))'=u'f'(u)
516/EvalFunc {
517  4 2 roll 4 index (1) ne
518  { AddOpPar 4 index StrConcat (\)*) StrConcat } if
519  (Eval             ) 4 8 index StrConcat 0 exch getinterval cvn cvx exec
520  2 copy pop 0 6 2 roll GetIntervalNewStr
521  mark 9 -3 roll cleartomark 2 index 6 index dup 4 index exch sub getinterval exch 6 2 roll
522} def
523%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
524%% Func derivative -> Eval<func>
525/EvalFunc_sin {%
526  PreCommonFunc
527  { (cos\() StrConcat 5 index StrConcat AddClPar } if
528  PostCommonFunc } def
529/EvalFunc_cos {%
530  PreCommonFunc
531  { (\(-sin\() StrConcat 5 index StrConcat (\)\)) StrConcat } if
532  PostCommonFunc } def
533/EvalFunc_tan {%
534  PreCommonFunc
535  {  dup 0 eq { (1) StrConcat } { 1 sub } ifelse  (/cos\() StrConcat 5 index StrConcat (\)^2) StrConcat } if
536  PostCommonFunc } def
537/EvalFunc_asin {%
538  PreCommonFunc
539  { (1/sqrt\(1-\() StrConcat 5 index StrConcat (\)^2\)\)) StrConcat } if
540  PostCommonFunc } def
541/EvalFunc_acos {%
542  PreCommonFunc
543  { (-1/sqrt\(1-\() StrConcat 5 index StrConcat (\)^2\)\)) StrConcat } if
544  PostCommonFunc } def
545/EvalFunc_atg {%
546  PreCommonFunc
547  { (1/\(1+\() StrConcat 5 index StrConcat (\)^2\)\)) StrConcat } if
548  PostCommonFunc } def
549/EvalFunc_ln {%
550  PreCommonFunc
551  {  dup 0 eq { (1) StrConcat } { 1 sub } ifelse (/\() StrConcat 5 index StrConcat AddClPar } if
552  PostCommonFunc } def
553/EvalFunc_exp {%
554  PreCommonFunc
555  {  (exp\() StrConcat 5 index StrConcat AddClPar } if
556  PostCommonFunc } def
557/EvalFunc_sqrt {%
558  PreCommonFunc
559  { dup 0 eq { (1) StrConcat } { 1 sub } ifelse (/\(2*sqrt\() StrConcat 5 index StrConcat (\)\)) StrConcat } if
560  PostCommonFunc } def
561/EvalFunc_Fact {%
562  PreCommonFunc { ERROR_no_variable_expression_in_Fact } if
563  PostCommonFunc } def
564/EvalFunc_sh {%
565  PreCommonFunc
566  { (ch\() StrConcat 5 index StrConcat AddClPar } if
567  PostCommonFunc } def
568/EvalFunc_ch {%
569  PreCommonFunc
570  { (sh\() StrConcat 5 index StrConcat AddClPar } if
571  PostCommonFunc } def
572/EvalFunc_th {%
573  PreCommonFunc
574  {  dup 0 eq { (1) StrConcat } { 1 sub } ifelse  (/ch\() StrConcat 5 index StrConcat (\)^2) StrConcat } if
575  PostCommonFunc } def
576/EvalFunc_Argsh {%
577  PreCommonFunc
578  { (1/sqrt\(1+\() StrConcat 5 index StrConcat (\)^2\)\)) StrConcat } if
579  PostCommonFunc } def
580/EvalFunc_Argch {%
581  PreCommonFunc
582  { (1/sqrt\(\() StrConcat 5 index StrConcat (\)^2-1\)\)) StrConcat } if
583  PostCommonFunc } def
584/EvalFunc_Argth {%
585  PreCommonFunc
586  { (1/\(1-\() StrConcat 5 index StrConcat (\)^2\)\)) StrConcat } if
587  PostCommonFunc } def
588%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
589/PreCommonFunc {
590  1 add NextNonBlankChar pop 3 -1 roll 5 1 roll AnalyzeExpr 1 add NextNonBlankChar pop
591  4 2 roll 4 index (0) eq
592  { (0) StrConcat false }
593  { 4 index (1)  ne { AddOpPar 4 index StrConcat (\)*) StrConcat } if true } ifelse
594} def
595/PostCommonFunc {
596  2 copy pop 0 6 2 roll GetIntervalNewStr
597  mark 9 -3 roll cleartomark 2 index 6 index dup 4 index exch sub getinterval exch 6 2 roll
598} def
599/EvalFunc_Derive {%
600  1 add ReadNumber cvi 1 add dup cvr log 1 add cvi string cvs
601  4 -1 roll pop 5 1 roll 1 add NextNonBlankChar pop AnalyzeExpr 1 add
602  4 -2 roll (Derive\() StrConcat 7 -1 roll StrConcat (,) StrConcat 6 -1 roll StrConcat AddClPar
603  2 copy pop 0 6 2 roll GetIntervalNewStr 6 -1 roll pop 2 index 6 index dup 4 index exch sub getinterval
604  exch 6 2 roll } def
605%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
606%% literal switch -> func call, vector, variables
607/EvalFunc_Sum {%
608  1 add NextNonBlankChar pop
609  %% read the variable name
610  ReadLiteral pop 3 -1 roll pop NextNonBlankChar
611  44 ne { ANALYZER_ERROR_missing_first_comma_in_Sum } if
612  %% read the initial value
613  1 add NextNonBlankChar pop ReadNumber pop
614  2 copy get 44 ne { ANALYZER_ERROR_missing_second_comma_in_Sum } if
615  %% read the increment value
616  1 add NextNonBlankChar pop ReadNumber pop
617  2 copy get 44 ne { ANALYZER_ERROR_missing_third_comma_in_Sum } if
618  %% read the limit value
619  1 add NextNonBlankChar pop ReadNumber pop
620  2 copy get 44 ne { ANALYZER_ERROR_missing_fourth_comma_in_Sum } if
621  1 add NextNonBlankChar pop dup 6 1 roll 3 -1 roll pop AnalyzeExpr 1 add NextNonBlankChar pop
622  4 -2 roll 3 index 8 index dup 9 index exch sub getinterval StrConcat
623  4 index StrConcat AddClPar
624  2 copy pop 0 6 2 roll GetIntervalNewStr
625  mark 9 -3 roll cleartomark 2 index 6 index dup 4 index exch sub getinterval exch 6 2 roll
626} def
627%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
628%% literal switch -> func call, vector, variables
629/EvalFunc_IfTE {%
630  3 -1 roll pop 1 add NextNonBlankChar pop SkipCond
631  NextNonBlankChar
632  44 ne { ANALYZER_ERROR_missing_first_comma_in_IfTE } if
633  1 add NextNonBlankChar pop dup 5 1 roll
634  AnalyzeExpr NextNonBlankChar
635  44 ne { ANALYZER_ERROR_missing_second_comma_in_IfTE } if
636  1 add NextNonBlankChar pop
637  AnalyzeExpr 1 add NextNonBlankChar pop
638  4 -2 roll 3 index 10 index dup 11 index exch sub getinterval StrConcat
639  6 index StrConcat (,) StrConcat 4 index StrConcat AddClPar
640  2 copy pop 0 6 2 roll GetIntervalNewStr
641  mark 11 -5 roll cleartomark 2 index 6 index dup 4 index exch sub getinterval exch 6 2 roll
642} def
643%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
644%% advance in str until a comma is found (no error detection!)
645%% str index -> str index'
646/SkipCond { { 1 add 2 copy get 44 eq {exit } if } loop } bind def
647%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
648%% Convert to radians if trigo function call
649%% (name) ->
650/TrigoFunc {
651  dup (cos) eq 1 index (sin) eq or exch (tan) eq or
652  { /ExpressionVector ExpressionVector aload length Pi /div cvx 180 /mul cvx 5 -1 roll 4 add
653    array astore def
654  } if
655} def
656%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
657%% No derivative for condition....
658/EvalCondOp { 3 -1 roll pop } bind def
659/PutIntervalOneAdd {putinterval 1 add} bind def
660%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
661%% Add open parenthesis in string at the given index
662%% str index -> str index+1
663/AddOpPar {2 copy (\() PutIntervalOneAdd} bind def
664%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
665%% Add close parenthesis in string at the given index
666%% str index -> str index+1
667/AddClPar {2 copy (\)) PutIntervalOneAdd} bind def
668%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
669%% Add 0 in string at the given index
670%% str index -> str index+1
671/AddZero {2 copy (0) PutIntervalOneAdd} bind def
672%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
673%% Add open parenthesis in string at the given index
674%% str index -> str index+1
675/AddMul {2 copy (*) PutIntervalOneAdd} bind def
676%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
677%% Add open parenthesis in string at the given index
678%% str index -> str index+1
679/AddDiv {2 copy (/) PutIntervalOneAdd} bind def
680%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
681%% Add a plus sign in string at the given index
682%% str index -> str index+1
683/AddAdd {2 copy (+) PutIntervalOneAdd} bind def
684%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
685%% Add a minus sign in string at the given index
686%% str index -> str index+1
687/AddSub {2 copy (-) PutIntervalOneAdd} bind def
688%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
689%% Add a pipe sign in string at the given index
690%% str index -> str index+1
691/AddPipe {2 copy (|) PutIntervalOneAdd} bind def
692%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
693%% H O O K S
694/AnalyzePreHook { dup 5 1 roll } bind def
695/PreEvalHook {} def
696/AnalyzePostHook { 7 -1 roll pop } bind def
697/AnalyzeListOfEPostHook { 6 -1 roll mark 6 1 roll cleartomark } bind def
698/RollOp { 5 1 roll } bind def
699end%%%tx@CoreAnalyzerDict
700/tx@AddMathFunc 12 dict def tx@AddMathFunc begin
701%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
702%% NEW FUNC
703%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
704%% function arcsine in radians asin(x)=atan(x/sqrt(1-x^2))
705%% x -> theta
706/asin {%
707  dup abs 1 gt { EQDFasinrangeerror  } if
708  dup dup dup mul 1 exch sub sqrt atan exch 0 lt { 360 sub } if DegtoRad
709} def
710%% function arccosine in radians acos(x)=atan(sqrt(1-x^2)/x)
711%% x -> theta
712/acos {%
713  dup abs 1 gt { EQDFacosrangeerror  } if
714  dup dup mul 1 exch sub sqrt exch atan DegtoRad
715} def
716%% function arctangent in radians
717%% x -> theta
718/atg { 1 atan dup 90 gt { 360 sub } if DegtoRad } bind def
719%% HYPERBOLIC FUNCTIONS
720/sh { dup Ex exch neg Ex sub 2 div } def
721/ch { dup Ex exch neg Ex add 2 div } def
722/th { dup sh exch ch div } def
723/Argsh { dup dup mul 1 add sqrt add ln } def
724/Argch { dup dup mul 1 sub sqrt add ln } def
725/Argth { dup 1 add exch 1 exch sub div ln 2 div } def
726%% modified exponential funtion for 0
727%% x n -> x^n
728/Exp { dup 0 eq { pop pop 1 } { exp } ifelse } bind def
729%% modified exponential funtion for 0
730%% x -> e^x
731/Ex { Euler exch exp } bind def
732%%
733%% factorial function
734%% n -> n!
735/Fact { 1 exch 2 exch 1 exch { mul } for } bind def
736/fact { Fact } bind def
737end
738
739% END pstricks.pro
Note: See TracBrowser for help on using the browser.