| 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 |
|---|
| 199 | end |
|---|
| 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 |
|---|
| 331 | end %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 |
|---|
| 699 | end%%%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 |
|---|
| 737 | end |
|---|
| 738 | |
|---|
| 739 | % END pstricks.pro |
|---|