% This file parses/evaluates a decimal expression.
%
% (c) 2007 Mark Wibrow
%
% but subject to the LaTeX Project Public License, 
% (http://www.latex-project.org/lppl.txt)
%
% and the GNU Public License,
% (http://www.gnu.org/licenses/gpl.txt)

% \pgfmathparse, \pgfmathqparse
%
% Evaluates a decimal expression.
%
% #1 - the expression.
%
% returns
%
% x = the result as a dimension.
%
% E.g.
% \pgfmathparse{3pt*2cm+1.5}
% \pgfmathqparse{3pt*2cm+1.5pt}
%
% Every number in \pgfmathqparse *must*
% specify a unit.
%
\newif\ifpgfmath@quickparse

\def\pgfmathparse{%
	\pgfmath@quickparsefalse%
	\pgfmathparse@}

\def\pgfmathqparse{%
	\pgfmath@quickparsetrue%
	\pgfmathparse@}
		
\def\pgfmathparse@#1{%
	\begingroup%
    % Reinstall correct font, so that dimensions like 1em are correct
	 \pgfutil@selectfont%
		\edef\pgfmath@temp{#1}%
		\pgfmath@resetparsingparameters%
		\global\pgfmathunitsdeclaredfalse%
		\ifpgfmath@quickparse%
			\let\pgfmath@parseoperand\pgfmath@quickparseoperand%
		\else%
			\let\pgfmath@parseoperand\pgfmath@parseoperand%
		\fi%
		\let\pgfmath@parsepostgroup\pgfmath@parseoperator%
		\expandafter\pgfmath@parse@\pgfmath@temp @@@@@@@@@@@\pgfmath@empty}


% \pgfmath@resetparsingparameters
%
% Reset the stack at the begining of the parse/group.
%
\def\pgfmath@resetparsingparameters{%
	\pgfmath@stack{\pgfmath@empty\pgfmath@empty\pgfmath@empty\pgfmath@empty}%
	\def\pgfmath@stacknextoperator{\pgfmath@empty}% Will not work with \let
}
% \pgfmath@parse@
%
% Start parsing. Expect one of
% 1) the end of the parse
% 2) the start of a group
% 3) a (possible) operand.
%
\def\pgfmath@parse@#1{%
	\def\pgfmath@token{}%
	\ifx#1@%
		\let\pgfmath@parsenext\pgfmath@endparse%
	\else%
		\ifx#1(%
			\let\pgfmath@parsenext\pgfmath@startparsegroup%
		\else%
			\edef\pgfmath@token{#1}%
			\let\pgfmath@parsenext\pgfmath@parseoperand%
	\fi\fi%
	\pgfmath@parsenext%
}

% If no TeX units are declared *at any point* in the parse
% the result is scaled by \pgfmathresultunitscale.
\newif\ifpgfmathunitsdeclared
\def\pgfmathsetresultunitscale#1{\def\pgfmathresultunitscale{#1}}
\def\pgfmathresultunitscale{1}

% \pgfmath@endparse
%
% Everything stops here.
%
\def\pgfmath@endparse#1\pgfmath@empty{%
	\pgfmath@processalloperations%
	\pgfmath@stackpop{\pgfmathresult}%
		\begingroup%
			\ifpgfmathunitsdeclared%
				\pgfmath@x1pt\relax%
			\else%
				\afterassignment\pgfmath@gobbletilpgfmath@%
				\pgfmath@x\pgfmathresultunitscale pt\relax\pgfmath@%
			\fi%
			\expandafter\pgfmath@x\pgfmathresult\pgfmath@x%
			\pgfmath@returnone\pgfmath@x%
		\endgroup%
		\pgfmath@smuggleone{\pgfmathresult}%
	\endgroup%
}

% \pgfmath@startparsegroup
%
% When opening ( is scanned start a new group.
%
\def\pgfmath@startparsegroup{%
	\begingroup%
		\let\pgfmath@parsepostgroup\pgfmath@parseoperator%
		\pgfmath@resetparsingparameters%
		\pgfmath@parse@}

% \pgfmath@endparsegroup
%
% When closing ) is scanned, processes all waiting
% operations (within the group) and close the group.
%
\def\pgfmath@endparsegroup{%
		\pgfmath@processalloperations%
		\pgfmath@stackpop{\pgfmathresult}%
		\expandafter\pgfmath@x\pgfmathresult pt\relax%
		\pgfmath@returnone\pgfmath@x%
	\endgroup%
	\pgfmath@parsepostgroup%
}

% \pgfmath@parseoperator
%
% An operator is expected here. 
% Or the end of the parse or parse group.
% 
\def\pgfmath@parseoperator#1{%
	\def\pgfmath@token{}%
	% Push the operand in \pgfmathresult on to the stack. 
	\expandafter\pgfmath@stackpushoperand\expandafter{\pgfmathresult}%
	\ifx#1@%
		\let\pgfmath@parsenext\pgfmath@endparse%
	\else%
		\ifx#1+%
			\let\pgfmath@parsenext\pgfmath@parseadd%
		\else%
			\ifx#1-%
				\let\pgfmath@parsenext\pgfmath@parsesubtract%
			\else%
				\ifx#1*%
					\let\pgfmath@parsenext\pgfmath@parsemultiply%
				\else%
					\ifx#1/%
						\let\pgfmath@parsenext\pgfmath@parsedivide%
					\else
						\ifx#1)%
							\let\pgfmath@parsenext\pgfmath@endparsegroup%
						\else%
							\ifx#1r%
								\let\pgfmath@parsenext\pgfmath@parseradians%
							\else%
								\ifx#1>%
									\let\pgfmath@parsenext\pgfmath@parsegreaterthan%
								\else%
									\ifx#1<%
										\let\pgfmath@parsenext\pgfmath@parselessthan%
									\else%
										\if#1=%
											\let\pgfmath@parsenext\pgfmath@parseequalto%
										\else%
											\if#1^%
												\let\pgfmath@parsenext\pgfmath@parsepower%
											\else%
												\pgfmath@error{Unknown operator `#1'}%
												\let\pgfmath@parsenext\relax%
	\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi%
	\pgfmath@parsenext%
}

% Use a \toks register as a stack.
\newtoks\pgfmath@stack

% \pgfmath@stackpushoperator
% 
% Push an operator (actually its macro e.g., \pgfmathadd@)
% on to the stack. And keep track of it using the macro
% \pgfmath@stacknextoperator.
%
\def\pgfmath@stackpushoperator#1{%
	\edef\pgfmath@temp{\noexpand#1\the\pgfmath@stack}%
	\expandafter\pgfmath@stack\expandafter{\pgfmath@temp}%
	\def\pgfmath@stacknextoperator{#1}}% <- Must \def. Cannot \let.

% \pgfmath@stackpushoperand
%
% Push an operand (i.e. a number) on the stack. It is
% put within a TeX group to make popping a lot simpler.
%
\def\pgfmath@stackpushoperand#1{%
	\edef\pgfmath@temp{{#1}\the\pgfmath@stack}%
	\expandafter\pgfmath@stack\expandafter{\pgfmath@temp}%
}

% \pgfmath@stackpeek
%
% Peek (i.e. without removal) at the top of the stack.
%
\def\pgfmath@stackpeek{\expandafter\pgfmath@stackpeek@\the\pgfmath@stack\pgfmath@}
\def\pgfmath@stackpeek@#1#2\pgfmath@{#1}%

% \pgfmath@stackpop
%
% Pop (i.e. remove) the top of the stack into #1.
%
\def\pgfmath@stackpop#1{\expandafter\pgfmath@stackpop@\expandafter#1\the\pgfmath@stack\pgfmath@}
\def\pgfmath@stackpop@#1#2#3\pgfmath@{\edef#1{#2}\pgfmath@stack{#3}}%

% \pgfmath@stackpopoperation
%
% Remove and perform an operation from the stack.
%
\def\pgfmath@stackpopoperation{%
	\expandafter\pgfmath@stackpopoperation@\the\pgfmath@stack\pgfmath@%
}
\def\pgfmath@stackpopoperation@#1#2#3#4#5\pgfmath@{%
	\ifx\pgfmath@empty#1\relax%
			\pgfmath@stack{\pgfmath@empty\pgfmath@empty\pgfmath@empty\pgfmath@empty}%
	\else%
		\ifx\pgfmath@empty#2\relax%
			\pgfmath@stack{{#1}\pgfmath@empty\pgfmath@empty\pgfmath@empty\pgfmath@empty}%
		\else%
			#2{#3}{#1}%
			\pgfmath@stack{#4#5}%
			\expandafter\pgfmath@stackpushoperand\expandafter{\pgfmathresult}%
	\fi\fi%
	\def\pgfmath@stacknextoperator{#4}}

% \pgfmath@processalloperations
%
% Process all operation in the stack. The 
% overall result is at the top of the stack.
%
\def\pgfmath@processalloperations{%
	\expandafter\pgfutil@in@\pgfmath@stacknextoperator{\pgfmath@empty}%
	\ifpgfutil@in@%
		\let\pgfmath@processnext\relax%		
	\else%
		\pgfmath@stackpopoperation%
		\let\pgfmath@processnext\pgfmath@processalloperations%
	\fi%
	\pgfmath@processnext}

% \pgfmath@processoperationsuntil
%
% Process operations in the stack, until the specified
% operation/s is/are encountered. The overall result is 
% at the top of the stack.
%
\def\pgfmath@processoperationsuntil#1{%
	\expandafter\pgfutil@in@\pgfmath@stacknextoperator{#1\pgfmath@empty}%
	\ifpgfutil@in@%
		\let\pgfmath@processnext\pgfmath@processoperationsuntil@end%		
	\else%
		\pgfmath@stackpopoperation%
		\let\pgfmath@processnext\pgfmath@processoperationsuntil%
	\fi%
	\pgfmath@processnext{#1}}
\def\pgfmath@processoperationsuntil@end#1{}


% OK. Now the operators are parsed.
% These correspond to the + - / * ^ < > = mod and r operators 
%
\def\pgfmath@parseadd{%	
	% If no operator has been assigned (i.e. + is the first operator scanned),
	% do nothing, except add addition to the stack.
	\ifx\pgfmath@stacknextoperator\pgfmath@empty%
	\else%
		% Empty the process stack up to any inequalities.
		\pgfmath@processoperationsuntil{\pgfmathequalto@\pgfmathlessthan@\pgfmathgreaterthan@}%
	\fi%
	\pgfmath@stackpushoperator{\pgfmathadd@}%
	\pgfmath@parse@}
	
\def\pgfmath@parsesubtract{%	
	% If no operator has been assigned (i.e. - is the first operator scanned),
	% do nothing, except add subtract to the stack.
	\ifx\pgfmath@stacknextoperator\pgfmath@empty%
	\else%
		% Empty the process stack up to any inequalities.
		\pgfmath@processoperationsuntil{\pgfmathequalto@\pgfmathlessthan@\pgfmathgreaterthan@}%
	\fi%
	\pgfmath@stackpushoperator{\pgfmathsubtract@}%
	\pgfmath@parse@}
	

\def\pgfmath@parsemultiply{%
	% If no operator has been assigned (i.e. * is the first operator scanned),
	% do nothing, except push multiply onto the stack.
	\ifx\pgfmath@stacknextoperator\pgfmath@empty%
	\else%
		% Process all operations up to inequalites or addition/subtraction
		\pgfmath@processoperationsuntil{\pgfmathequalto@\pgfmathlessthan@\pgfmathgreaterthan@%
			\pgfmathadd@\pgfmathsubtract@}%
	\fi%
	\pgfmath@stackpushoperator{\pgfmathmultiply@}%
	\pgfmath@parse@}
	
\def\pgfmath@parsedivide{%
	% If no operator has been assigned (i.e. / is the first operator scanned),
	% do nothing, except push divide onto the stack.
	\ifx\pgfmath@stacknextoperator\pgfmath@empty%
	\else%
		% Process all operations up to inequalites or addition/subtraction
		\pgfmath@processoperationsuntil{\pgfmathequalto@\pgfmathlessthan@\pgfmathgreaterthan@%
			\pgfmathadd@\pgfmathsubtract@}%
	\fi%
	\pgfmath@stackpushoperator{\pgfmathdivide@}%
	\pgfmath@parse@}

\def\pgfmath@parsegreaterthan{%
	% On scanning an equality/inequality operator everything up to
	% (but not including) the operator is evaluated... 
	\pgfmath@processalloperations%
	% ...and the operation pushed onto the stack.
	\pgfmath@stackpushoperator{\pgfmathgreaterthan@}%
	\pgfmath@parse@}

\def\pgfmath@parselessthan{%
	\pgfmath@processalloperations%
	\pgfmath@stackpushoperator{\pgfmathlessthan@}%
	\pgfmath@parse@}

\def\pgfmath@parseequalto={%
	\pgfmath@processalloperations%
	\pgfmath@stackpushoperator{\pgfmathequalto@}%
	\pgfmath@parse@}

\def\pgfmath@parsepower{%
	% Easy, just push power onto the stack.
	\pgfmath@stackpushoperator{\pgfmathpow@}%
	\pgfmath@parse@}

\def\pgfmath@parseradians{%
	% Actually this is a post-fix function...
	\ifx\pgfmath@primaryoperation\pgfmath@empty%
	\else%
		\pgfmath@processoperationsuntil{\pgfmathequalto@\pgfmathlessthan@\pgfmathgreaterthan@%
			\pgfmathadd@\pgfmathsubtract@}%
	\fi%	
	\pgfmath@stackpop{\pgfmath@temp}%
	\pgfmathdeg@{\pgfmath@temp}%
	% ...so processing returns to \pgfmath@parseoperator
	\pgfmath@parseoperator}
	
\newcount\c@pgfmath@parsecounta
\newcount\c@pgfmath@parsecountb
\newcount\c@pgfmath@parsecountc
\newdimen\pgfmath@parsex

% \pgfmath@quickparseoperand
%
% An operand can *only* be a dimension.
%
\def\pgfmath@quickparseoperand{%
	\afterassignment\pgfmath@quickparseoperand@%
	\pgfmath@parsex\pgfmath@token}
\def\pgfmath@quickparseoperand@{%
	\edef\pgfmathresult{\pgfmath@tonumber{\pgfmath@parsex}}
	\pgfmath@parseoperator%
}
	
% \pgfmath@parseoperand
%
% An operand can be an ASCII number (with or without dimensions, with
% or without a decimal point), a TeX register (count, dimen or skip,
% which may have expanded with \the), or a function e.g. sin(X).
%
% It is assumed that after \edef-ing, the only unexpanded tokens are registers. 
%
\def\pgfmath@parseoperand{%
	\def\pgfmath@sign{}%
	\expandafter\pgfmath@parseoperandsign\pgfmath@token}
\def\pgfmath@parseoperandsign#1{%
	\pgfmath@in@#1{-+}% 
	\ifpgfmath@in@
		% I suppose there are (silly) people who might complain if
		% they can't say 2---5, or 3+-----7. Just for them...
		\edef\pgfmath@sign{\pgfmath@sign#1}%
		\expandafter\pgfmath@parseoperandsign%
	\else%
		\expandafter\pgfmath@parsenumberorfunction\expandafter#1%
	\fi%
}


\newif\ifpgfmath@dimen@

\def\pgfmath@ifregisterdimen@#1\pgfmath@{%
	\pgfmath@in@{p}{#1}%
	\ifpgfmath@in@%
		\pgfmath@dimen@true%
	\else%
		\pgfmath@dimen@false%
	\fi} 	
		

\def\pgfmath@parsenumberorfunction#1{%
  \let\pgfmath@parsenext\pgfmath@parsenumberorfunction@simple%
  \ifx#1\wd\let\pgfmath@parsenext\pgfmath@boxdimen\fi%
  \ifx#1\ht\let\pgfmath@parsenext\pgfmath@boxdimen\fi%
  \ifx#1\dp\let\pgfmath@parsenext\pgfmath@boxdimen\fi%
  \pgfmath@parsenext#1%
}

\def\pgfmath@boxdimen#1#2{%
  \pgfmath@parsex=#1#2%
  \edef\pgfmathresult{\pgfmath@tonumber{\pgfmath@parsex}}%
  \global\pgfmathunitsdeclaredtrue% a dimension has units 
  \pgfmath@parseoperator%
}

\def\pgfmath@parsenumberorfunction@simple#1{%	
	\expandafter\ifcat#1\relax%
		% So, a TeX register.
		\afterassignment\pgfmath@ifregisterdimen@%
		\pgfmath@parsex\pgfmath@sign#1pt\relax\pgfmath@%
		\ifpgfmath@dimen@% 
			% A dimension! So stop scanning operand here.
			\edef\pgfmathresult{\pgfmath@tonumber{\pgfmath@parsex}}%
         \global\pgfmathunitsdeclaredtrue% a dimension has units
			\def\pgfmath@temp{}%
			\let\pgfmath@parsenext\pgfmath@parseoperator%
		\else%
			% A count! Expand it, but carry on as usual as it might
			% be immediately followed by a dimension.
			\ifdim\pgfmath@parsex<0pt\relax%
				\edef\pgfmath@sign{\pgfmath@sign-}%
				\pgfmath@parsex-\pgfmath@parsex%
			\fi%
			\edef\pgfmath@temp{\pgfmath@tonumber{\pgfmath@parsex}}%
			\let\pgfmath@parsenext\pgfmath@parsenumberorfunction@%
		\fi%
	\else%
		% Could be a number or a function...?
		\edef\pgfmath@temp{#1}%
		\let\pgfmath@parsenext\pgfmath@parsenumberorfunction@%
	\fi%
	\expandafter\pgfmath@parsenext\pgfmath@temp%
}%

\def\pgfmath@parsenumberorfunction@#1{%
	\pgfmath@in@{#1}{.0123456789}%
	\ifpgfmath@in@%
		\let\pgfmath@parsenext\pgfmath@parsenumber%
	\else%
		\let\pgfmath@parsenext\pgfmath@parsefunction%
	\fi%
	\pgfmath@parsenext#1%
}%

\def\pgfmath@parsenumber{% 
	% Consider the number 3.14159
	% 3 is parsed by assignment to a, then '.' is absorbed and 14159
	% parsed by assignement to b (actually b=114159, see below). 
	\c@pgfmath@parsecountc0\relax%
	\afterassignment\pgfmath@parsedecimalpoint%
	\c@pgfmath@parsecounta0}

\def\pgfmath@parsedecimalpoint#1{%
	\ifx#1.% Is there a decimal point? If not, see if there are any units.
		\let\pgfmath@parsenext\pgfmath@parsemantissa%
	\else%
		\c@pgfmath@parsecountb10\relax% The first digit of b is gobbled (see below). 
		\let\pgfmath@parsenext\pgfmath@parseunits%
	\fi%
	\pgfmath@parsenext#1}



% We would like to assign the following number (which is the mantisse)
% to a number. However, for a very long mantisse as in 3.141592653589793238462643
% this will fail since the number becomes too large.
%
% Because of this, we have to do some ``magic'': We scan 9 tokens and
% then do an assignment with a guard after 9 tokens so that the
% assigment cannot fail.
%
\def\pgfmath@parsemantissa.#1#2#3#4#5#6#7#8#9{%
  \afterassignment\pgfmath@checkforguard%    
  % Consider the number: 2.005
  % 2 is assigned to a, but b will be assigned 5, which is *not right*. 
  % So using 1 here hereresults in  b=1005. The first digit is then  
  % gobbled later, when expanded with \the.
  \c@pgfmath@parsecountb1#1#2#3#4#5#6#7#8#9\relax}%

\def\pgfmath@checkforguard{%
  \pgfutil@ifnextchar\relax%
  {%
    % Ok, this is a looong mantisse. Start gobbling all following
    % numbers
    \pgfmath@gobblemantisse%
  }%
  {%
    \pgfmath@removeguard%
  }%
}

\def\pgfmath@gobblemantisse\relax#1#2#3#4#5#6#7#8#9{%
  \afterassignment\pgfmath@checkforguard%
  \c@pgfmath@parsecountc0#1#2#3#4#5#6#7#8#9\relax% these digits are ignored
}

\def\pgfmath@removeguard#1\relax{\pgfmath@parseunits#1}



 
\def\pgfmath@parseunits#1{%
  % Here the extra first digit in b is gobbled. 
  \edef\pgfmath@resulttemp{%
    \pgfmath@sign\the\c@pgfmath@parsecounta.\expandafter\pgfmath@gobbleone\the\c@pgfmath@parsecountb}%
  % Check whether #1 is a \dp, \wd, or \ht
  \let\pgfmath@parsenext=\pgfmath@parseunits@simple%
  \ifx#1\wd\let\pgfmath@parsenext=\pgfmath@parseunits@boxdimen\fi%
  \ifx#1\ht\let\pgfmath@parsenext=\pgfmath@parseunits@boxdimen\fi%
  \ifx#1\dp\let\pgfmath@parsenext=\pgfmath@parseunits@boxdimen\fi%
  \pgfmath@parsenext#1%
}

\def\pgfmath@parseunits@boxdimen#1#2{%
  \pgfmath@parsex=#1#2%
  \pgfmath@parsex\pgfmath@resulttemp\pgfmath@parsex%
  \edef\pgfmathresult{\pgfmath@tonumber{\pgfmath@parsex}}%
  \global\pgfmathunitsdeclaredtrue% a dimension has units 
  \pgfmath@parseoperator%
}

\def\pgfmath@parseunits@simple#1{%
	% Now check if #1 is actually a register.
	\ifcat#1\relax%
		\afterassignment\pgfmath@ifregisterdimen@%
		\pgfmath@parsex#1pt\relax\pgfmath@%
		\pgfmath@parsex\pgfmath@resulttemp\pgfmath@parsex%
		\ifpgfmath@dimen@% If it's a dimen stop scanning operand here.
                        \global\pgfmathunitsdeclaredtrue% a dimension has units
			\edef\pgfmathresult{\pgfmath@tonumber{\pgfmath@parsex}}%
			\let\pgfmath@parsenext\pgfmath@parseoperator%
		\else
			\edef\pgfmath@resulttemp{\pgfmath@tonumber{\pgfmath@parsex}}%
			\let\pgfmath@parsenext\pgfmath@parseunits@%
		\fi%
		\expandafter\pgfmath@parsenext%
	\else%
		\expandafter\pgfmath@parseunits@\expandafter#1%
	\fi}

\def\pgfmath@parseunits@#1#2{%
	% Check if #1 is an operator, or the character `@' indicating the end of the parse.
	\pgfmath@in@#1{@+-*/^r<>=()}%
	\ifpgfmath@in@%
		\edef\pgfmath@tokens{#1#2}%
		\edef\pgfmathresult{\pgfmath@resulttemp}%
		\let\pgfmath@parsenext\pgfmath@parseoperator%
	\else%
		\pgfmath@in@#1{Ee}% e+0X
		\ifpgfmath@in@%
			% Oh no! It might be and em or an ex...
			\pgfmath@in@#2{mx}%
			\ifpgfmath@in@%
				\global\pgfmathunitsdeclaredtrue%
				\pgfmath@parsex\pgfmath@resulttemp#1#2\relax%
				\edef\pgfmathresult{\pgfmath@tonumber{\pgfmath@parsex}}%
				\edef\pgfmath@tokens{}%
				\let\pgfmath@parsenext\pgfmath@parseoperator%
			\else%
				\edef\pgfmath@tokens{#2}%
				\let\pgfmath@parsenext\pgfmath@parsescientific%
			\fi%
		\else
			% Anything else *should* be a TeX unit.
			\global\pgfmathunitsdeclaredtrue%
			\pgfmath@parsex\pgfmath@resulttemp#1#2\relax%
			\edef\pgfmathresult{\pgfmath@tonumber{\pgfmath@parsex}}%
			\edef\pgfmath@tokens{}%
			\let\pgfmath@parsenext\pgfmath@parseoperator%
	\fi\fi%
	\expandafter\pgfmath@parsenext\pgfmath@tokens%
}

% Parse 'Scientific' notation in the form xEyy
%
\def\pgfmath@parsescientific{%
	\afterassignment\pgfmath@parsescientific@%
	\c@pgfmath@parsecounta}

\def\pgfmath@parsescientific@{%
	\edef\pgfmath@parsesci@temp{\pgfmath@resulttemp\the\c@pgfmath@parsecountc}%
	\expandafter\pgfmathscientific\expandafter{\pgfmath@parsesci@temp}%
		{\the\c@pgfmath@parsecounta}%
	\edef\pgfmath@resulttemp{\pgfmathresult}%
	\pgfmath@parseunits@}

	
% OK. Now the fun stuff. We parse functions here. Note that 
% *no* calulations are done in the following macros. All the
% mathematics is done in pgfmathoperations.code and friends. 
%
% Functions dealt with here are:
%
% round(X)         'half-up' rounding.
% floor(X)         floor function.
% ciel(X)          ceiling function.
% abs(X)           absolute function.
%
% exp(X)           e^X (0 <= X <~= 9.7).
%
% sin(X)           sine function.
% cos(X)           cosine function.
% tan(X)           tan function.
% asin(X)          arcsine of X (in radians)    -1 <= X <= 1
% acos(X)          arccosine of X (in radians)  -1 <= X <= 1
% atan(X)          arctangent of X (in radians) -1 <= X <= 1
% veclen(X,Y)      the length Z where Z^2 = X^2 + Y^2
% mod(X,Y)         X modulo Y
% max(X,Y)         the maximum of X or Y
% min(X,Y)         the minimum of X or Y
%
% NB veclen, mod, max, and min *cannot* be nested.
%
% deg(X)           converts X to degrees (X in radians)
% rad(X)           converts X to radians (X in degrees)
%
% rnd              generate pseudo-random number X (0 <= X <= 1).
% rand             generate pseudo-random number X (1 <= X <= -1).
% sqrt(X)          square root.
% 
% pi               the constant PI.

\def\pgfmath@parsefunction{%
	\def\pgfmath@parsedfunctionname{}%
	\futurelet\pgfmath@parsetoken\pgfmath@parsefunction@@}
\def\pgfmath@parsefunction@@#1{%
	\pgfmath@in@#1{()@+-*/^<>=}% A function name ends with one of these...
	\ifpgfmath@in@%
		\let\pgfmath@parsefunctionnext\pgfmath@parsefunction@end%
	\else%
		\ifx\pgfmath@parsetoken\pgfutil@sptoken% ...or a space.
			\let\pgfmath@parsefunctionnext\pgfmath@parsefunction@end%
		\else%
			\let\pgfmath@parsefunctionnext\pgfmath@parsefunction@continue%
	\fi\fi%
	\pgfmath@parsefunctionnext#1}

\def\pgfmath@parsefunction@end#1{%
	\expandafter\ifx\csname pgfmath@parsefunction@\pgfmath@parsedfunctionname\endcsname\relax%
		\pgfmath@reportunknownfunction%
		\let\pgfmath@parsefunctionnext\relax%
	\else%
		\let\pgfmath@parsefunctionnext\pgfmath@executeparsefunction@%
	\fi%
	\pgfmath@parsefunctionnext#1}

\def\pgfmath@parsefunction@continue#1{%
	\edef\pgfmath@parsedfunctionname{\pgfmath@parsedfunctionname#1}%
	\futurelet\pgfmath@parsetoken\pgfmath@parsefunction@@}
	
\def\pgfmath@executeparsefunction@{\csname pgfmath@parsefunction@\pgfmath@parsedfunctionname\endcsname}
		
		
\def\pgfmath@reportunknownfunction{%
	\pgfmath@error{Unknown function `\pgfmath@parsedfunctionname'}{}%
}

% \pgfmath@postfunction
% 
% In scanning a function e.g. sin(40), we subvert the normal parsing 
% group mechanism by messing around with \pgfmath@parsepostgroup, so 
% that after scanning ), the parser doesn't scan for an operator, but 
% returns to the macros scanning the function. 
% Here the mechanism is restored, and the value of the function is 
% stored along with the approprate sign, which was saved earlier.
%
\def\pgfmath@postfunction{%
	\let\pgfmath@parsepostgroup\pgfmath@parseoperator%
	\edef\pgfmathresult{\pgfmath@sign\pgfmathresult}%
	\pgfmath@parseoperator}
	

% \pgfmath@parsefunction@abs
%
\def\pgfmath@parsefunction@abs{%
	\let\pgfmath@parsepostgroup\pgfmath@parsefunction@abs@%
	\expandafter\pgfmath@parse@}
\def\pgfmath@parsefunction@abs@{%	
	\expandafter\pgfmathabs@\expandafter{\pgfmathresult}%
	\pgfmath@postfunction%
}

% \pgfmath@parsefunction@sqrt
%
\def\pgfmath@parsefunction@sqrt{%
	\let\pgfmath@parsepostgroup\pgfmath@parsefunction@sqrt@%
	\expandafter\pgfmath@parse@}
\def\pgfmath@parsefunction@sqrt@{%	
	\expandafter\pgfmathsqrt@\expandafter{\pgfmathresult}%
	\pgfmath@postfunction%
}

% \pgfmath@parsefunction@round
%
\def\pgfmath@parsefunction@round{%
	\let\pgfmath@parsepostgroup\pgfmath@parsefunction@round@%
	\expandafter\pgfmath@parse@}
\def\pgfmath@parsefunction@round@{%	
	\expandafter\pgfmathround@\expandafter{\pgfmathresult}%
	\pgfmath@postfunction%
}

% \pgfmath@parsefunction@floor
%
\def\pgfmath@parsefunction@floor{%
	\let\pgfmath@parsepostgroup\pgfmath@parsefunction@floor@%
	\expandafter\pgfmath@parse@}
\def\pgfmath@parsefunction@floor@{%	
	\expandafter\pgfmathfloor@\expandafter{\pgfmathresult}%
	\pgfmath@postfunction%
}

% \pgfmath@parsefunction@ceil
%
\def\pgfmath@parsefunction@ceil{%
	\let\pgfmath@parsepostgroup\pgfmath@parsefunction@ceil@%
	\expandafter\pgfmath@parse@}
\def\pgfmath@parsefunction@ceil@{%	
	\expandafter\pgfmathceil@\expandafter{\pgfmathresult}%
	\pgfmath@postfunction%
}

% \pgfmath@parsefunction@sin
%
\def\pgfmath@parsefunction@sin{%
	\let\pgfmath@parsepostgroup\pgfmath@parsefunction@sin@%
	\expandafter\pgfmath@parse@}
\def\pgfmath@parsefunction@sin@{%	
	\expandafter\pgfmathsin@\expandafter{\pgfmathresult}%
	\pgfmath@postfunction%
}

% \pgfmath@parsefunction@cos
%
\def\pgfmath@parsefunction@cos{%
	\let\pgfmath@parsepostgroup\pgfmath@parsefunction@cos@%
	\expandafter\pgfmath@parse@}
\def\pgfmath@parsefunction@cos@{%	
	\expandafter\pgfmathcos@\expandafter{\pgfmathresult}%
	\pgfmath@postfunction%
}

% \pgfmath@parsefunction@asin
%
\def\pgfmath@parsefunction@asin{%
	\let\pgfmath@parsepostgroup\pgfmath@parsefunction@asin@%
	\expandafter\pgfmath@parse@}
\def\pgfmath@parsefunction@asin@{%	
	\expandafter\pgfmathasin@\expandafter{\pgfmathresult}%
	\pgfmath@postfunction%
}

% \pgfmath@parsefunction@acos
%
\def\pgfmath@parsefunction@acos{%
	\let\pgfmath@parsepostgroup\pgfmath@parsefunction@acos@%
	\expandafter\pgfmath@parse@}
\def\pgfmath@parsefunction@acos@{%	
	\expandafter\pgfmathacos@\expandafter{\pgfmathresult}%
	\pgfmath@postfunction}

% \pgfmath@parsefunction@atan
%
\def\pgfmath@parsefunction@atan{%
	\let\pgfmath@parsepostgroup\pgfmath@parsefunction@atan@%
	\expandafter\pgfmath@parse@}
\def\pgfmath@parsefunction@atan@{%	
	\expandafter\pgfmathatan@\expandafter{\pgfmathresult}%
	\pgfmath@postfunction%
}

% \pgfmath@parsefunction@tan
%
\def\pgfmath@parsefunction@tan{%
	\let\pgfmath@parsepostgroup\pgfmath@parsefunction@tan@%
	\expandafter\pgfmath@parse@}
\def\pgfmath@parsefunction@tan@{%	
	\expandafter\pgfmathtan@\expandafter{\pgfmathresult}%
	\pgfmath@postfunction%
}

% \pgfmath@parsefunction@rad
%
\def\pgfmath@parsefunction@rad{%
	\let\pgfmath@parsepostgroup\pgfmath@parsefunction@rad@%
	\pgfmath@parse@}
\def\pgfmath@parsefunction@rad@{%
	\expandafter\pgfmathrad@\expandafter{\pgfmathresult}%
	\pgfmath@postfunction}%
	
% \pgfmath@parsefunction@rad
%
\def\pgfmath@parsefunction@deg{%
	\let\pgfmath@parsepostgroup\pgfmath@parsefunction@deg@%
	\expandafter\pgfmath@parse@}
\def\pgfmath@parsefunction@deg@{%
	\expandafter\pgfmathdeg@\expandafter{\pgfmathresult}%
	\pgfmath@postfunction}%
	
% \pgfmath@parsefunction@rnd
%
\def\pgfmath@parsefunction@rnd{%
	\expandafter\pgfmathrnd%
	\expandafter\pgfmath@postfunction}
			
% \pgfmath@parsefunction@rand
%
\def\pgfmath@parsefunction@rand{%
	\expandafter\pgfmathrand%
	\expandafter\pgfmath@postfunction}%
			
% \pgfmath@parsefunction@exp
%
\def\pgfmath@parsefunction@exp{%
	\let\pgfmath@parsepostgroup\pgfmath@parsefunction@exp@%
	\expandafter\pgfmath@parse@}
\def\pgfmath@parsefunction@exp@{%	
	\expandafter\pgfmathexp@\expandafter{\pgfmathresult}%
	\pgfmath@postfunction%
}

% \pgfmath@parsefunction@pi
%
\def\pgfmath@parsefunction@pi{%
	\pgfmathpi%
	\pgfmath@postfunction%
}


% \pgfmath@parsefunction@veclen
%
\def\pgfmath@parsefunction@veclen{%
	\expandafter\pgfmath@parsefunction@veclen@}
\def\pgfmath@parsefunction@veclen@(#1,{%
	\pgfmathparse@{#1}\edef\pgfmath@firstoperand{\pgfmathresult}%
	\let\pgfmath@parsepostgroup\pgfmath@parsefunction@veclen@@
	\pgfmath@startparsegroup}
\def\pgfmath@parsefunction@veclen@@{%
	\edef\pgfmath@secondoperand{\pgfmathresult}%
	\pgfmathveclen@{\pgfmath@firstoperand}{\pgfmath@secondoperand}%
	\pgfmath@postfunction}

% \pgfmath@parsefunction@mod 
%
\def\pgfmath@parsefunction@mod{%
	\expandafter\pgfmath@parsefunction@mod@}
\def\pgfmath@parsefunction@mod@(#1,{%
	\pgfmathparse@{#1}\edef\pgfmath@firstoperand{\pgfmathresult}%
	\let\pgfmath@parsepostgroup\pgfmath@parsefunction@mod@@
	\pgfmath@startparsegroup}
\def\pgfmath@parsefunction@mod@@{%
	\edef\pgfmath@secondoperand{\pgfmathresult}%
	\pgfmathmod@{\pgfmath@firstoperand}{\pgfmath@secondoperand}%
	\pgfmath@postfunction}

% \pgfmath@parsefunction@max
%
\def\pgfmath@parsefunction@max{%
	\expandafter\pgfmath@parsefunction@max@}
\def\pgfmath@parsefunction@max@(#1,{%
	\pgfmathparse@{#1}\edef\pgfmath@firstoperand{\pgfmathresult}%
	\let\pgfmath@parsepostgroup\pgfmath@parsefunction@max@@
	\pgfmath@startparsegroup}
\def\pgfmath@parsefunction@max@@{%
	\edef\pgfmath@secondoperand{\pgfmathresult}%
	\pgfmathmax@{\pgfmath@firstoperand}{\pgfmath@secondoperand}%
	\pgfmath@postfunction}	

% \pgfmath@parsefunction@min 
%
\def\pgfmath@parsefunction@min{%
	\expandafter\pgfmath@parsefunction@min@}
\def\pgfmath@parsefunction@min@(#1,{%
	\pgfmathparse@{#1}\edef\pgfmath@firstoperand{\pgfmathresult}%
	\let\pgfmath@parsepostgroup\pgfmath@parsefunction@min@@
	\pgfmath@startparsegroup}
\def\pgfmath@parsefunction@min@@{%
	\edef\pgfmath@secondoperand{\pgfmathresult}%
	\pgfmathmin@{\pgfmath@firstoperand}{\pgfmath@secondoperand}%
	\pgfmath@postfunction}
	
% \pgfmath@parsefunction@pow 
%
\def\pgfmath@parsefunction@pow{%
	\expandafter\pgfmath@parsefunction@pow@}
\def\pgfmath@parsefunction@pow@(#1,{%
	\pgfmathparse@{#1}\edef\pgfmath@firstoperand{\pgfmathresult}%
	\let\pgfmath@parsepostgroup\pgfmath@parsefunction@pow@@
	\pgfmath@startparsegroup}
\def\pgfmath@parsefunction@pow@@{%
	\edef\pgfmath@secondoperand{\pgfmathresult}%
	\pgfmathpow@{\pgfmath@firstoperand}{\pgfmath@secondoperand}%
	\pgfmath@postfunction}