Name: CompileMath - converts traditional math to postfix notation

Synopsis:

string CompileMath -&gt; proc


Examples:

( 5 + 3 * 7 )      CompileMath  exec  --&gt; 26 
( 5 * (3 + 7) )    CompileMath  exec  --&gt; 50 
( 5 + x * 7 )      CompileMath        --&gt; {5 x 7 mul add} 
( 3 + exp 5 )      CompileMath        --&gt; {3 5 exp add} 
( 3 + exp (  x ) ) CompileMath        --&gt; {3 x exp add} 
( 3 + exp ( -x ) ) CompileMath        --&gt; {3 x neg exp add} 
( 3 * exp (sin 2)) CompileMath        --&gt; {3 2 sin exp mul} 
( 3 * exp sin 2 )  CompileMath        --&gt; {3 2 sin exp mul} 
(4 * - 7)          CompileMath exec   --&gt; -28 
(2^3)              CompileMath        --&gt; {2 3 pow} 
(5+3*2^3)          CompileMath        --&gt; {5 3 2 3 pow mul add} 
(5+3*2^3-4)        CompileMath        --&gt; {5 3 2 3 pow mul add 4 sub} 
(5+3*2^3/4)        CompileMath        --&gt; {5 3 2 3 pow mul 4 div add} 
(5+3*2^-3)         CompileMath        --&gt; {5 3 2 3 neg pow mul add} 
(4)                CompileMath        --&gt; {4} 
()                 CompileMath        --&gt; {} 
(a=7+3)            CompileMath        --&gt; {/a 7 3 add dup rolld Set} 
(a=7+3;)           CompileMath        --&gt; {/a 7 3 add dup rolld Set pop} 
(a=7+3;6)          CompileMath        --&gt; {/a 7 3 add dup rolld Set pop 6} 
(a=7+4;b=2*exp(-2.0/10)) CompileMath  --&gt; {/a 7 4 add dup rolld Set pop /b 2 2.0 neg 10 div exp mul dup rolld Set} 
(Function({x+2},'x)) CompileMath      --&gt; {{x 2 add} /x Function} 
(f=Function({x+2},'x)) CompileMath    --&gt; {/f {x 2 add} /x Function dup rolld Set} 
(f={#+2})              CompileMath    --&gt; {/f {&lt;&lt; &gt;&gt; begin /# Set # 2 add end} dup rolld Set} 
(f={#1-#2})            CompileMath    --&gt; {/f {&lt;&lt; &gt;&gt; begin /#2 Set /#1 Set #1 #2 sub end} dup rolld Set} 
({#1-#2})            CompileMath exec --&gt; {&lt;&lt; &gt;&gt; begin /#2 Set /#1 Set #1 #2 sub end} 
([4,3,2])              CompileMath    --&gt; {[4 3 2]} 
(x=7+[4,3,2]*2)        CompileMath    --&gt; {/x 7 [ 4 3 2 ] 2 mul add dup rolld Set} 
([])                   CompileMath    --&gt; {[]} 
(&lt;&lt; 'x : [-3, 9]*2, 'y : 7 &gt;&gt;) CompileMath --&gt; {&lt;&lt; /x [ 3 neg 9 ] 2 mul /y 7 &gt;&gt;} 
(&lt;&lt; &gt;&gt;)                CompileMath    --&gt; {&lt;&lt; &gt;&gt;} 
(5+3 // Function( {2*x+1},'x)  ) CompileMath exec  --&gt; 17 
(1+(5+3 // Function( {2*x+1},'x))  ) CompileMath exec  --&gt; 18 
( [ 3, [ 2, 1], -9] // Flatten) CompileMath exec --&gt; [3 2 1 -9] 
( [ 3, [ 2, 1], -9] // Flatten // {Select(#,{#&lt;3})}  ) CompileMath exec --&gt; [2 1 -9] 
(5+3 // {#+1}  ) CompileMath exec --&gt; 9 
(7 5 // {#1-#2}) CompileMath exec --&gt; 2


Description:

CompileMath converts a string containing a mathematical expression 
in traditional infix notation to a procedure using the 
standard postfix notation of SLI. The algorithm is: 
1. replace traditonal operators like "-" and "+" with 
SLI literals like /sub and /add 
2. decompose the string into tokens using the standard 
SLI scanner 
3. compile the sequence of tokens to a SLI postfix expression 
using the predictive recursive-descent parser described in 
chapter 2 of the Dragon Book. 
The result is the unevaluated expression. This enables the user 
to store the expression for later reevaluation.


Parameters:

string, is the mathematical expression 
proc, is the unevaluated expression in SLI postfix notation


Bugs:

The present version fails for doubles with negative exponents 
because the lexer just replaces all "-" with /sub. A slightly 
smarter lexer using a regular expression can solve this problem.


Remarks:

The function can be improved by using a more powerful parsing 
scheme. The predictive recursive parsing scheme is used here 
as an educational example.


References:

[1] The Dragon Book, 1988, chapter 2


Author:

Diesmann


FirstVersion:

090117


SeeAlso:

Inline
ExecMath
cst
cvx
exec

Source:

/var/www/debian/nest/nest-simulator-2.20.0/lib/sli/mathematica.sli
