
\newdimen\pgfmath@dimen
\newcount\pgfmath@count
\newbox\pgfmath@box
\newtoks\pgfmath@toks

\newif\ifpgfmath@quickparse
\newif\ifpgfmathfloat
\newif\ifpgfmathunitsdeclared
\newif\ifpgfmathmathunitsdeclared
\newif\ifpgfmathignoreunitscale

\def\pgfmathprint#1{\pgfmathparse{#1}\pgfmathresult}

\def\pgfmathparse{%
  \begingroup
    \pgfmath@catcodes
    \pgfmath@quickparsefalse
    % Test for the fpu library
    \ifpgfmathfloat
      \let\pgfmath@parse@next=\pgfmathfloatparsenumber
    \else
      \let\pgfmath@parse@next=\pgfmathparse@
    \fi
    \pgfmath@parse@next}

\def\pgfmath@catcodes{% Maybe unecessary.
  \catcode`\==12 %
  \catcode`\,=12 %
  \catcode`\|=12 %
  \catcode`\&=12 %
}

\def\pgfmathqparse{%
  \begingroup
    \pgfmath@catcodes
    \pgfmath@quickparsetrue
    \pgfmathparse@}
  
\def\pgfmathparse@#1{%
    % No (math) units yet. 
    \global\pgfmathunitsdeclaredfalse
    \global\pgfmathmathunitsdeclaredfalse
    % Expand expression so any reamining CSs are registers
    % or box dimensions (i.e. |\wd|, |\ht|, |\dp|).
    \edef\pgfmath@expression{#1}%
	%
	\expandafter\pgfmathparse@trynumber@loop\pgfmath@expression\pgfmath@parse@stop
	%
	% this here is the _real_ parser. it is invoked by
	% \pgfmathparse@trynumber@loop if that says "this is no number"
	%\pgfmathparse@@\pgfmath@parse@stop%
}

\def\pgfmath@parse@stop{\pgfmath@parse@stop}% equals only itsself

\def\pgfmathparse@trynumber@token{numeric}
\begingroup
\def\\{\global\let\pgf@let@space@token= } \\ % now, \pgf@let@space@token is a space token
\endgroup

% This a "fast-lane": if the expressions consist merely of number
% tokens, we can simply return the number as-is.
%
% This is significantly faster and should resemble the 80% use-case.
%
% #1 a single token
\def\pgfmathparse@trynumber@loop{%
	\futurelet\pgfmath@token@let\pgfmathparse@trynumber@loop@
}%
\def\pgfmathparse@trynumber@loop@#1{%
	\ifx\pgfmath@token@let\pgf@let@space@token
		% Hm. we found a white space... and we have no support for
		% trimming. That means we have to assume that the white space
		% occurred somewhere in the middle - and fall back to the
		% expensive method.
		\def\pgfmath@parse@next{\pgfmathparse@@#1}%
	\else
		\ifx\pgfmath@token@let\bgroup%
			% oh! We found '{' #1.
			% Well, these braces appear to be special; fall back to
			% the complicated routine...
			\let\pgfmath@parse@next=\pgfmathparse@@
		\else
			\ifx\pgfmath@token@let\pgfmath@parse@stop
				% Ah: we have passed the check! The expression consists only
				% of 0123456789. , so do not parse anything and return it
				% as-is!
				\let\pgfmath@parse@next=\pgfmathparse@expression@is@number
			\else
				\expandafter\ifx\csname pgfmath@token@\pgfmathparse@trynumber@token @\string#1\endcsname\relax%
					% hm. It is none of 0123456789.
					\let\pgfmath@parse@next=\pgfmathparse@@
				\else
					% continue... we only found one of 0123456789. so
					% far...
					\let\pgfmath@parse@next=\pgfmathparse@trynumber@loop
				\fi
			\fi
		\fi
	\fi
	\pgfmath@parse@next
}%

\def\pgfmathparse@expression@is@number{%
	\let\pgfmathresult=\pgfmath@expression
    \pgfmath@smuggleone\pgfmathresult%
  \endgroup
  \ignorespaces
}%
\def\pgfmathparse@@#1\pgfmath@parse@stop{%
    % We are inside a group (opened in |\pgfmathparse| or
    % |\pgfmathqparse|). 
    % Stuff for calc compatiability.
    \let\real=\pgfmath@calc@real
    \let\minof=\pgfmath@calc@minof
    \let\maxof=\pgfmath@calc@maxof
    \let\ratio=\pgfmath@calc@ratio
    \let\widthof=\pgfmath@calc@widthof
    \let\heightof=\pgfmath@calc@heightof
    \let\depthof=\pgfmath@calc@depthof
    % Restore font (defined in pgfmathutil.code.tex)
    \pgfmath@selectfont
    % Set up stack.
    \pgfmath@stack@operation={{}{}{}}%
    \pgfmath@stack@operand={{}{}{}}%
    \let\pgfmath@stack@operation@top=\pgfmath@stack@empty
    \let\pgfmath@stack@operand@top=\pgfmath@stack@empty
    % An expression always begins with an operand.
    \expandafter\pgfmath@bgroup@strip\expandafter{\pgfmath@expression}%
    % |\pgfmath@bgroup@stripped| is the result of
    % |\pgfmath@bgroup@strip|
    \expandafter\pgfmath@parse@@operand\pgfmath@bgroup@stripped @@@@\pgfmath@parse@stop%
}

\def\pgfmath@parse@end#1\pgfmath@parse@stop{%
    \pgfmathpostparse
    \pgfmath@smuggleone\pgfmathresult%
  \endgroup
  \ignorespaces}

\let\pgfmathpostparse=\relax

% For compatiability with older version.
%
\def\pgfmathscaleresult{%
  \ifpgfmathunitsdeclared
  \else
    \ifpgfmathignoreunitscale
    \else
       \afterassignment\pgfmath@gobbletilpgfmath@%
      \pgfmath@x\pgfmathresultunitscale pt\relax\pgfmath@%
      \expandafter\pgfmath@x\pgfmathresult\pgfmath@x%
      \edef\pgfmathresult{\pgfmath@tonumber{\pgfmath@x}}%
    \fi
  \fi
}

\def\pgfmathsetresultunitscale#1{\def\pgfmathresultunitscale{#1}}

\def\pgfmathresultunitscale{1}


% A utility function which evaluates expression '#1' and invokes '#2'
% if the expression is true and '#3' if it is false.
\def\pgfmathifexpression#1#2#3{%
    \pgfmathparse{#1}%
    \pgfmath@iftrue{#2}{#3}%
}%
% Executes '#1' if \pgfmathresult is 'true', '#2' otherwise.
% WARNING : overwritten in fpu lib!
\def\pgfmath@iftrue{%
    \ifdim\pgfmathresult pt=1.0pt %
        \let\pgfmath@next=\pgfutil@firstoftwo
    \else
        \let\pgfmath@next=\pgfutil@secondoftwo
    \fi
    \pgfmath@next%
}%

% Stuff for compatability with the calc package.
%
\def\pgfmath@calc@real#1{#1}
\def\pgfmath@calc@minof#1#2{min(#1,#2)}
\def\pgfmath@calc@maxof#1#2{max(#1,#2)}
\def\pgfmath@calc@ratio#1#2{#1/#2}
\def\pgfmath@calc@widthof#1{width("#1")}
\def\pgfmath@calc@heightof#1{height("#1")}
\def\pgfmath@calc@depthof#1{depth("#1")}

\def\pgfmath@bgroup{\string\pgfmath@bgroup}
\def\pgfmath@egroup{\string\pgfmath@egroup}
\def\pgfmath@egroup@token{\pgfmath@egroup}

\def\pgfmath@text@@{@}
\def\pgfmath@text@operator{operator}
\def\pgfmath@text@function{function}
\def\pgfmath@dots{...}
\def\pgfmath@char@zero{0}
\def\pgfmath@char@quote{"}
\def\pgfmath@char@exclamation{!}
\def\pgfmath@char@plus{+}
\def\pgfmath@char@minus{-}
\def\pgfmath@char@period{.}
\def\pgfmath@char@leftangle{<}
\def\pgfmath@char@leftbracket{[}
\pgfmath@toks={#}
\edef\pgfmath@char@hash{\the\pgfmath@toks}

\def\pgfmath@tokens@make#1#2{%
  % Defines for each token or balenced text in |#2| a control sequence
  % |\pgfmath@token@<#1>@\string<one token from #2>| and stores |#2|
  % in it.
  \def\pgfmath@prefix{#1}%
  % Note the empty group |{}| at the end that ends the loop in
  % |\pgfmath@token@@make|.
  \expandafter\pgfmath@tokens@@make#2{}}
  
\def\pgfmath@tokens@@make#1{%
  \def\pgfmath@token{#1}%
  \ifx\pgfmath@token\pgfmath@empty
    % End of loop: all tokens or balanced texts were parsed.
  \else
    \pgfmath@namedef{pgfmath@token@\pgfmath@prefix @\string#1}{#1}%
    \expandafter\pgfmath@tokens@@make%
  \fi}

\pgfmath@tokens@make{box}{\wd\ht\dp}
\ifx\dimexpr\@undefined\else % needed for classic tex
  \pgfmath@tokens@make{dimexpr}{\dimexpr\glueexpr}
\fi
\pgfmath@tokens@make{unit}{{bp}{cc}{cm}{dd}{em}{ex}{in}{mm}{pc}{pt}{sp}}
\pgfmath@tokens@make{mathunit}{{mu}}
\pgfmath@tokens@make{numeric}{.0123456789}
\pgfmath@tokens@make{number}{0123456789}
\pgfmath@tokens@make{functional}{_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNPQRSTUVWXYZ}
\pgfmath@tokens@make{exponent}{eE}
\pgfmath@tokens@make{group}{{()}{[]}{\pgfmath@bgroup\pgfmath@egroup}}
\pgfmath@tokens@make{specials}{@)]\pgfmath@egroup}
\pgfmath@tokens@make{hexadecimal}{0123456789ABCDEFabcdef}
\pgfmath@tokens@make{octal}{01234567}
\pgfmath@tokens@make{binary}{01}

\pgfmath@namedef{pgfmath@base@0x}{16}
\pgfmath@namedef{pgfmath@base@0X}{16}
\pgfmath@namedef{pgfmath@base@0b}{2}
\pgfmath@namedef{pgfmath@base@0B}{2}

% Determine if a register is a count or a dimension/skip register.
\newif\ifpgfmath@dimen@
\def\pgfmath@dimen@#1{%
  \begingroup
    \afterassignment\pgfmath@dimen@@%
    #1=0.0pt\relax\pgfmath@}
\def\pgfmath@dimen@@#1#2\pgfmath@{%
  \endgroup
  \ifx#1.%
    \pgfmath@dimen@false
  \else
    \pgfmath@dimen@true
  \fi}

\def\pgfmath@parse@ifbgroup#1#2{%
  \let\pgfmath@parse@bgroup@after=#1%
  \let\pgfmath@parse@nobgroup@after=#2%
  \futurelet\pgfmath@token@let%
  \pgfmath@parse@@ifbgroup}
  
\def\pgfmath@parse@@ifbgroup{%
  \ifx\pgfmath@token@let\bgroup
    \let\pgfmath@parse@next=\pgfmath@parse@@@ifbgroup
  \else
    % |\pgfmath@sptoken| defined in \file{pgfmathutil.code.tex}.
    \ifx\pgfmath@token@let\pgfmath@sptoken
      \let\pgfmath@parse@next=\pgfmath@parse@@@@ifbgroup
    \else
      \let\pgfmath@parse@next=\pgfmath@parse@nobgroup@after
    \fi
  \fi
  \pgfmath@parse@next}

% TT: If false, octal parsing is switched off (needed for time parsing)
\newif\ifpgfmath@octalparsing
\pgfmath@octalparsingtrue

% I (CJ) *think* it replaces |{| and |}| by |\pgfmath@bgroup| and
% |\pgfmath@egroup|?
\def\pgfmath@parse@@@ifbgroup#1{%
  \pgfmath@parse@bgroup@after\pgfmath@bgroup#1\pgfmath@egroup}

{
\def\:{\pgfmath@parse@@@@ifbgroup}
\expandafter\gdef\: {\futurelet\pgfmath@token@let\pgfmath@parse@@ifbgroup}
}

% Parse an operand.
\def\pgfmath@parse@operand{%
  \expandafter\pgfmath@parse@@operand\pgfmath@token@next}

% This is the entry point for the parser. It is called at the end of
% |\pgfmathparse@| with the following syntax
% |\expandafter\pgfmath@parse@@operand\pgfmath@bgroup@stripped
% @@@@\pgfmath@parse@stop|.
% Note: we are inside a group.
\def\pgfmath@parse@@operand{%
  \pgfmath@parse@ifbgroup{\pgfmath@parse@@operand}{\pgfmath@parse@@operand@}}

% An operand is 
% * |+| (unary plus),
% * |-| (unary minus), 
% * a prefix operator
\def\pgfmath@parse@@operand@#1{%
  \def\pgfmath@token{#1}%
  \ifx\pgfmath@token\pgfmath@char@plus
    % Unary (prefix) plus
    \let\pgfmath@parse@next=\pgfmath@parse@@operand%
  \else
    \ifx\pgfmath@token\pgfmath@char@minus
      % Unary (prefix) minus
      \pgfmath@stack@push@operation{neg}%
      \let\pgfmath@parse@next=\pgfmath@parse@@operand
    \else
      % See |\pgfmathdeclareoperator| (below). Note that |+| and |-|
      % that are also declared as operators have been tested before so
      % they should never be parsed as binary (infix) operator at this stage.
      \expandafter\ifx\csname pgfmath@operation@\expandafter\string\pgfmath@token @prefix\endcsname\pgfmath@token
        \let\pgfmath@parse@next=\pgfmath@parse@prefix@operator
      \else
        \ifpgfmath@quickparse
          \let\pgfmath@parse@next=\pgfmath@qparse@operand
        \else
          \let\pgfmath@number=\pgfmath@empty
          \expandafter\ifx\csname pgfmath@token@functional@\string#1\endcsname\relax%
            \let\pgfmath@base=\pgfmath@empty%
            \let\pgfmath@token@next=\pgfmath@token%
            \if#10% Check for octal prefix.
              \ifpgfmath@octalparsing%
                \def\pgfmath@base{8}%
              \fi%
            \fi%
            \let\pgfmath@parse@next=\pgfmath@parse@number%
          \else%
            \let\pgfmath@function=\pgfmath@token%
            \let\pgfmath@parse@next=\pgfmath@parse@function%
          \fi%
        \fi%
      \fi%
    \fi%
  \fi%
  \pgfmath@parse@next%
}

% Parse prefix operators.
%
\def\pgfmath@parse@prefix@operator{%
  \ifx\pgfmath@token\pgfmath@char@quote% Quote character.
    \let\pgfmath@parse@next=\pgfmath@parse@operand@quote%
  \else%
    \ifx\pgfmath@token\pgfmath@char@exclamation% Prefix !.
      \pgfmath@stack@push@operation{not}%
      \let\pgfmath@parse@next=\pgfmath@parse@@operand%
    \else% Anything else, just push and hope.
      \expandafter\pgfmath@stack@push@operation\expandafter{\pgfmath@token}%
      \let\pgfmath@parse@next=\pgfmath@parse@@operand%
    \fi%
  \fi%
  \pgfmath@parse@next%
}%


% Quote part of an expression.
%
\def\pgfmath@parse@operand@quote#1"{%
  \def\pgfmathresult{#1}%
  \expandafter\pgfmath@stack@push@operand\expandafter{\pgfmathresult}%
  \pgfmath@parse@@operator%
}

% Quick operand parsing. Should always have units.
% No functions, base conversion, quoting or scientific notation
% are permitted.
\def\pgfmath@qparse@operand{%
  \afterassignment\pgfmath@qparse@@operand%
  \pgfmath@dimen\pgfmath@token}
\def\pgfmath@qparse@@operand{%
  \edef\pgfmathresult{\pgfmath@tonumber{\pgfmath@dimen}}%
  \expandafter\pgfmath@stack@push@operand\expandafter{\pgfmathresult}%
  \pgfmath@parse@@operator%
}

% Parse a number, which can take the form:
%
% 1. An integer, or a decimal, with or without units.
% 2. A dimension/skip or a count register.
% 3. A dimension register preceded by a number or count register.
% 4. A box dimension (e.g., \wd\mybox).
% 5. A box dimension preceded by a number or a count register.
% 6. Scientific notation (e.g., 1.234567e-10).
% 7. A binary, hexadeciaml, or octal number.
%  
\def\pgfmath@parse@number{\pgfmath@parse@ifbgroup{\pgfmath@parse@number}{\pgfmath@parse@number@}}
\def\pgfmath@parse@number@#1{%
  \let\pgfmath@token=\pgfmath@token@next%
  \def\pgfmath@token@next{#1}%
  \pgfmath@parse@@number}

\def\pgfmath@parse@@number{%
  \ifx\pgfmath@token\pgfmath@egroup@token%
    \expandafter\pgfmath@stack@push@operand\expandafter{\pgfmath@number}%
    \let\pgfmath@parse@next=\pgfmath@parse@@@operator%
  \else%
    \expandafter\ifcat\pgfmath@token\relax% A CS?
      \expandafter\ifx\csname pgfmath@token@dimexpr@\expandafter\string\pgfmath@token\endcsname\relax%
        \expandafter\ifx\pgfmath@token\numexpr%
          \let\pgfmath@parse@next=\pgfmath@parse@numexpr%
        \else%
          \expandafter\ifx\pgfmath@token\muexpr%
            \let\pgfmath@parse@next=\pgfmath@parse@muexpr%
          \else%
            \expandafter\ifx\csname pgfmath@token@box@\expandafter\string\pgfmath@token\endcsname\relax%
              % So, is the CS is a dimension or a count register?
              \expandafter\pgfmath@dimen@\pgfmath@token%
              \ifpgfmath@dimen@% A dimension register.
                \global\pgfmathunitsdeclaredtrue%
                \pgfmath@dimen=\pgfmath@number\pgfmath@token%
                \edef\pgfmathresult{\pgfmath@tonumber{\pgfmath@dimen}}%
                \expandafter\pgfmath@stack@push@operand\expandafter{\pgfmathresult}%
                \let\pgfmath@parse@next=\pgfmath@parse@operator%
              \else% A count register.
                \pgfmath@count=\pgfmath@token%
                \expandafter\def\expandafter\pgfmath@number\expandafter{\the\pgfmath@count}%
                \expandafter\ifcat\pgfmath@token@next\relax%
                  % A CS following a count register should be \wd, \ht or \dp. 
                  \let\pgfmath@parse@next=\pgfmath@parse@number%
                \else%
                  \let\pgfmathresult=\pgfmath@number%
                  \expandafter\pgfmath@stack@push@operand\expandafter{\pgfmathresult}%
                  \let\pgfmath@parse@next=\pgfmath@parse@operator%
                \fi%
              \fi%
            \else%
              % This should be a box specification, for example, 0.5\wd\mybox.
              \global\pgfmathunitsdeclaredtrue%
              \pgfmath@dimen=\pgfmath@number\pgfmath@token\pgfmath@token@next%
              \edef\pgfmathresult{\pgfmath@tonumber{\pgfmath@dimen}}%
              \expandafter\pgfmath@stack@push@operand\expandafter{\pgfmathresult}%
              \let\pgfmath@parse@next=\pgfmath@parse@@operator%
            \fi%
          \fi%
        \fi%
      \else%
        \global\pgfmathunitsdeclaredtrue%
        \let\pgfmath@parse@next=\pgfmath@parse@dimexpr%
      \fi%
    \else%
      \expandafter\ifx\csname pgfmath@token@numeric@\expandafter\string\pgfmath@token\endcsname\relax%
        % It isn't numeric (i.e., 012345679.), so it might be units...
        \expandafter\ifx\csname pgfmath@token@unit@\pgfmath@token\expandafter\string\pgfmath@token@next\endcsname\relax%
          % ...or the exponent characters...
          \expandafter\ifx\csname pgfmath@token@exponent@\pgfmath@token\endcsname\relax%
            % ...or a base prefix...
            \expandafter\ifx\csname pgfmath@base@\pgfmath@number\pgfmath@token\endcsname\relax%
              % ...or a math unit...
              \expandafter\ifx\csname pgfmath@token@mathunit@\pgfmath@token\expandafter\string\pgfmath@token@next\endcsname\relax%
                % ...none of the above...
                  \ifx\pgfmath@base\pgfmath@empty%
                    \let\pgfmathresult=\pgfmath@number% 
                  \else%
                    \ifx\pgfmath@number\pgfmath@char@zero%
                      \let\pgfmathresult=\pgfmath@number%
                    \else%
                      % Convert from octal.
                      \expandafter\pgfmathbasetobase\expandafter\pgfmathresult\expandafter{\pgfmath@number}{8}{10}%
                    \fi%
                  \fi%
                  \expandafter\pgfmath@stack@push@operand\expandafter{\pgfmathresult}%
                  \let\pgfmath@parse@next=\pgfmath@parse@@@operator%
              \else%
                % ...here, it is a math unit (mu). Treat it as a pt.
                \global\pgfmathunitsdeclaredtrue%
                \global\pgfmathmathunitsdeclaredtrue%
                \pgfmath@dimen=\pgfmath@number pt\relax%
                \edef\pgfmathresult{\pgfmath@tonumber{\pgfmath@dimen}}%
                \expandafter\pgfmath@stack@push@operand\expandafter{\pgfmathresult}%
                \let\pgfmath@parse@next=\pgfmath@parse@@operator%
              \fi%
            \else%
              % ...here, it is a base prefix 0x, 0X, 0b or 0B
              \expandafter\let\expandafter\pgfmath@base\expandafter=%
                \csname pgfmath@base@\pgfmath@number\pgfmath@token\endcsname%
              \let\pgfmath@parse@next=\pgfmath@parse@base%
            \fi%
          \else% ... and here, it is the exponent characters.
            \let\pgfmath@parse@next=\pgfmath@parse@exponent%          
          \fi%
        \else% ...but here it is units.
          \global\pgfmathunitsdeclaredtrue%
          \pgfmath@dimen=\pgfmath@number\pgfmath@token\pgfmath@token@next\relax%
          \edef\pgfmathresult{\pgfmath@tonumber{\pgfmath@dimen}}%
          \expandafter\pgfmath@stack@push@operand\expandafter{\pgfmathresult}%
          \let\pgfmath@parse@next=\pgfmath@parse@@operator%
        \fi%
      \else% It is numeric.
        \expandafter\expandafter\expandafter\def\expandafter\expandafter\expandafter\pgfmath@number%
          \expandafter\expandafter\expandafter{\expandafter\pgfmath@number\pgfmath@token}%
        \ifx\pgfmath@token\pgfmath@char@period%
          \let\pgfmath@base=\pgfmath@empty%
        \fi%
        \let\pgfmath@parse@next=\pgfmath@parse@number%
      \fi%
    \fi%
  \fi%
  \pgfmath@parse@next%
}


% Parse a \dimexpr
\def\pgfmath@parse@dimexpr{%
  \afterassignment\pgfmath@parse@dimexpr@%
  \expandafter\expandafter\expandafter\pgfmath@dimen\expandafter\pgfmath@token\pgfmath@token@next%
}
\def\pgfmath@parse@dimexpr@{%
  \edef\pgfmathresult{\pgfmath@tonumber{\pgfmath@dimen}}%
  \expandafter\pgfmath@stack@push@operand\expandafter{\pgfmathresult}%
  \pgfmath@parse@@operator%
}


% Parse a \muexpr
\def\pgfmath@parse@muexpr{%
  \begingroup%
    \afterassignment\pgfmath@parse@muexpr@%
    \expandafter\expandafter\expandafter\muskip\expandafter\expandafter\expandafter0\expandafter\pgfmath@token\expandafter\pgfmath@token@next%
}
\def\pgfmath@parse@muexpr@{%
  \expandafter\endgroup%
  \expandafter\edef\expandafter\pgfmathresult\expandafter{\expandafter\pgfMATH@STRIPMU\the\muskip0}%
  \expandafter\pgfmath@stack@push@operand\expandafter{\pgfmathresult}%
  \pgfmath@parse@@operator%
}

{
\catcode`\m=12
\catcode`\u=12
\gdef\pgfMATH@STRIPMU#1mu{#1}
}


% Parse a \numexpr
\def\pgfmath@parse@numexpr{%
  \afterassignment\pgfmath@parse@numexpr@%
  \expandafter\expandafter\expandafter\pgfmath@count\expandafter\pgfmath@token\pgfmath@token@next%
}
\def\pgfmath@parse@numexpr@#1{%
  \expandafter\def\expandafter\pgfmath@number\expandafter{\the\pgfmath@count}%
  \def\pgfmath@token@next{#1}%
  \expandafter\ifcat\pgfmath@token@next\relax%
    % A CS following a count register should be \wd, \ht or \dp. 
    \let\pgfmath@parse@next=\pgfmath@parse@number%
  \else%
    \let\pgfmathresult=\pgfmath@number%
    \expandafter\pgfmath@stack@push@operand\expandafter{\pgfmathresult}%
    \let\pgfmath@parse@next=\pgfmath@parse@operator%
  \fi%
  \pgfmath@parse@next%
}


% Parse the exponent of a number.
%
% REMARK: this method will be overwritten by the FPU library. Please
% keep changes consistent...
\def\pgfmath@parse@exponent{%
  \afterassignment\pgfmath@parse@@exponent%
  \pgfmath@count\pgfmath@token@next}
\def\pgfmath@parse@@exponent{%
  \pgfmathscientific{\pgfmath@number}{\the\pgfmath@count}%
  \expandafter\pgfmath@stack@push@operand\expandafter{\pgfmathresult}%
  \pgfmath@parse@@operator%
}

% Parse binary or hexadecimal numbers (octal numbers done elsehwere).
%
\def\pgfmath@parse@base{%
  \ifnum\pgfmath@base=2\relax%
    \let\pgfmath@parse@next=\pgfmath@parse@binary%
  \else%
    \ifnum\pgfmath@base=16\relax%
      \let\pgfmath@parse@next=\pgfmath@parse@hexadecimal%
    \else%
      \pgfmath@error{Unexpected numerical base `\pgfmath@base'}{}%
      \def\pgfmathresult{0}%
      \let\pgfmath@parse@next=\pgfmath@parse@end%
    \fi%
  \fi%
  \let\pgfmath@number=\pgfmath@empty%
  \expandafter\pgfmath@parse@next\pgfmath@token@next%
}
  
\def\pgfmath@parse@binary#1{%
  \expandafter\ifx\csname pgfmath@token@binary@#1\endcsname\relax%
    \expandafter\pgfmathbasetobase\expandafter\pgfmathresult\expandafter{\pgfmath@number}{2}{10}%
    \expandafter\pgfmath@stack@push@operand\expandafter{\pgfmathresult}%
    \def\pgfmath@token@next{#1}%
    \let\pgfmath@parse@next=\pgfmath@parse@operator%
  \else%
    \expandafter\def\expandafter\pgfmath@number\expandafter{\pgfmath@number#1}%
    \let\pgfmath@parse@next=\pgfmath@parse@binary%
  \fi%
  \pgfmath@parse@next%
}

\def\pgfmath@parse@hexadecimal#1{%
  \expandafter\ifx\csname pgfmath@token@hexadecimal@#1\endcsname\relax%
    \expandafter\pgfmathbasetobase\expandafter\pgfmathresult\expandafter{\pgfmath@number}{16}{10}%
    \expandafter\pgfmath@stack@push@operand\expandafter{\pgfmathresult}%
    \def\pgfmath@token@next{#1}%
    \let\pgfmath@parse@next=\pgfmath@parse@operator%
  \else%
    \expandafter\def\expandafter\pgfmath@number\expandafter{\pgfmath@number#1}%
    \let\pgfmath@parse@next=\pgfmath@parse@hexadecimal%
  \fi%
  \pgfmath@parse@next%
}
  
% Parse a function.
%
\def\pgfmath@parse@function{\pgfmath@parse@ifbgroup{\pgfmath@parse@function}{\pgfmath@parse@@function}}
\def\pgfmath@parse@function@{\futurelet\pgfmath@token@let\pgfmath@parse@@function}
\def\pgfmath@parse@@function{%
  \ifx\pgfmath@token@let\pgfmath@sptoken%
    \let\pgfmath@token=\pgfmath@empty%
    \let\pgfmath@parse@next=\pgfmath@parse@@@@function%
  \else%
    \let\pgfmath@parse@next=\pgfmath@parse@@@function%
  \fi%
  \pgfmath@parse@next}

\def\pgfmath@parse@@@function#1{%
  \expandafter\ifx\csname pgfmath@token@functional@\expandafter\string#1\endcsname\relax%
    \expandafter\ifx\csname pgfmath@token@number@\expandafter\string#1\endcsname\relax%
      \def\pgfmath@token{#1}% Not from A-Z, a-z, 0-9, or _.
      \let\pgfmath@parse@next=\pgfmath@parse@@@@function%
    \else% It is from 0-9.
      \expandafter\def\expandafter\pgfmath@function\expandafter{\pgfmath@function#1}%
      \let\pgfmath@parse@next=\pgfmath@parse@function@%
    \fi%
  \else% It is from from A-Z, a-z, or _.
    \edef\pgfmath@function{\pgfmath@function#1}%
    \let\pgfmath@parse@next=\pgfmath@parse@function@%
  \fi%
  \pgfmath@parse@next}

\def\pgfmath@parse@@@@function{%
  \expandafter\ifx\csname pgfmath@function@\pgfmath@function\endcsname\relax%
    \pgfmath@error{Unknown function `\pgfmath@function'}{}%
    \def\pgfmathresult{0}%
    \let\pgfmath@parse@next=\pgfmath@parse@end%
  \else%
    \expandafter\ifnum\csname pgfmath@operation@\pgfmath@function @arity\endcsname=0\relax%
     % Functions with zero arity are called directly.
      \csname pgfmath\pgfmath@function @\endcsname%
      \expandafter\pgfmath@stack@push@operand\expandafter{\pgfmathresult}%
      \let\pgfmath@parse@next=\pgfmath@parse@@operator%
    \else% Otherwise, they are pushed onto the operator stack
      \expandafter\pgfmath@stack@push@operation\expandafter{\pgfmath@function}%
      \let\pgfmath@parse@next=\pgfmath@parse@@operand%
    \fi%
  \fi%
  \expandafter\pgfmath@parse@next\pgfmath@token}

% Parse an operator.
%
\def\pgfmath@parse@operator{\pgfmath@parse@ifbgroup{\pgfmath@parse@operator}{\pgfmath@parse@operator@}}%
\def\pgfmath@parse@operator@#1{% Get one token.
  \let\pgfmath@token=\pgfmath@token@next%
  \def\pgfmath@token@next{#1}%
  \pgfmath@parse@@@operator}

\def\pgfmath@parse@@operator{\pgfmath@parse@ifbgroup{\pgfmath@parse@@operator}{\pgfmath@parse@@operator@}}%
\def\pgfmath@parse@@operator@#1{% Get first token...
  \def\pgfmath@token{#1}%
  \pgfmath@parse@ifbgroup{\pgfmath@parse@@operator@@}{\pgfmath@parse@@operator@@}}%
\def\pgfmath@parse@@operator@@#1{% ...and second token.
  \def\pgfmath@token@next{#1}%
  \pgfmath@parse@@@operator}  

\def\pgfmath@parse@@@operator{%
  \expandafter\ifx\csname pgfmath@operator@\pgfmath@token\expandafter\string\pgfmath@token@next\endcsname\relax%
    % Not a double character operator.
    \expandafter\ifx\csname pgfmath@operator@\pgfmath@token\endcsname\relax%
      % Not a single character operator.
      \pgfmath@error{Unknown operator `\pgfmath@token' or `\pgfmath@token\pgfmath@token@next'}{}%
      \def\pgfmathresult{0}%
    \let\pgfmath@parse@next=\pgfmath@parse@end%
    \else%
      \expandafter\pgfmath@operation@process\expandafter{\pgfmath@token}%
      \ifx\pgfmath@token\pgfmath@text@@%
        \let\pgfmath@parse@next=\pgfmath@parse@end%
      \else%
        \expandafter\ifx\csname pgfmath@operation@\pgfmath@token @postfix\endcsname\pgfmath@token%
          % Postfix operators are followed by an operator.
          \ifx\pgfmath@token@next\pgfmath@char@leftbracket% Except [.
            \let\pgfmath@parse@next=\pgfmath@parse@operand%
          \else%
            \let\pgfmath@parse@next=\pgfmath@parse@operator%
          \fi%
        \else%
          % Any other operator is followed by an operand.
          \let\pgfmath@parse@next=\pgfmath@parse@operand%
        \fi%
      \fi%
    \fi%
  \else%
    % A double character operator...
    \expandafter\expandafter\expandafter\def\expandafter\expandafter\expandafter%
      \pgfmath@token\expandafter\expandafter\expandafter%
        {\expandafter\pgfmath@token\pgfmath@token@next}%
    \expandafter\pgfmath@operation@process\expandafter{\pgfmath@token}%
    % ...is always followed by an operand.
    \let\pgfmath@parse@next=\pgfmath@parse@@operand%
  \fi%
  \pgfmath@parse@next%
}


% Process an operation.
%
\def\pgfmath@operation@process#1{%
  \def\pgfmath@operator{#1}%
  \ifx\pgfmath@stack@operation@top\pgfmath@stack@empty%
  \else%
    \pgfmath@operation@@process%
  \fi%
  \expandafter\ifx\csname pgfmath@token@specials@#1\endcsname\relax%
    \pgfmath@stack@push@operation{#1}%
  \fi%
}

% Process the operation stack.
%
\def\pgfmath@operation@@process{%
  \ifx\pgfmath@stack@operation@top\pgfmath@stack@empty%
    \let\pgfmath@parse@next=\relax%
  \else%
    \ifnum\csname pgfmath@operation@\pgfmath@operator @precedence\endcsname>%
      \csname pgfmath@operation@\pgfmath@stack@operation@top @precedence\endcsname\relax%
      % If the precedence of the scanned operator is greater than the
      % precedence of the operator at the top of the stack, do nothing.
      \let\pgfmath@parse@next=\relax%
    \else%
      \let\pgfmath@stack@operation@last=\pgfmath@stack@operation@top%
      \expandafter\ifx\csname pgfmath@operator@\pgfmath@stack@operation@top\endcsname\relax%
        \pgfmath@function@@@process%
      \else%
        \pgfmath@operator@@@process%
      \fi%
      \expandafter\pgfmath@stack@push@operand\expandafter{\pgfmathresult}%
      \expandafter\ifx\csname pgfmath@token@group@\pgfmath@stack@operation@last\pgfmath@operator\endcsname\relax%
        \let\pgfmath@parse@next=\pgfmath@operation@@process%
      \else%
        \let\pgfmath@parse@next=\relax%
      \fi%
    \fi%
  \fi%
  \pgfmath@parse@next%
}

% Process an operator.
%
\def\pgfmath@operator@@@process{% Process an operator.
  \pgfmath@stack@pop@operation\pgfmath@@operator%
  \pgfmath@stack@pop@operand\pgfmath@operand@a%  
  \ifcase\csname pgfmath@operation@\pgfmath@@operator @arity\endcsname\relax%
    % Zero arity operators (!).
  \or%    
    \pgfmath@operator@@@@process{\pgfmath@operand@a}%
  \or%
    \pgfmath@stack@pop@operand\pgfmath@operand@b%
    \pgfmath@operator@@@@process{\pgfmath@operand@b}{\pgfmath@operand@a}%
  \or%
    \pgfmath@stack@pop@operand\pgfmath@operand@b%
    \expandafter\pgfmath@operator@@@@process\expandafter%
      {\expandafter\pgfmath@operand@b\expandafter}\pgfmath@operand@a%    
  \else%
    % No operators with more than tenary arity.
  \fi%
}

\def\pgfmath@operator@@@@process{%
  \csname pgfmath%
    \csname pgfmath@operation@\pgfmath@@operator @name\endcsname%
  @\endcsname}

% Process a function.
%
\def\pgfmath@function@@@process{% Process a function.
  \ifnum\csname pgfmath@operation@\pgfmath@stack@operation@top @arity\endcsname>0\relax%
    \pgfmath@stack@pop@operation\pgfmath@@function%
    \pgfmath@stack@pop@operand\pgfmath@@operand%
    \ifnum\csname pgfmath@operation@\pgfmath@@function @arity\endcsname>1\relax%
      \ifnum\csname pgfmath@operation@\pgfmath@@function @arity\endcsname>9\relax%
        \csname pgfmath\pgfmath@@function @\endcsname{\pgfmath@@operand}%
      \else%
        \expandafter\pgfmath@function@@@@process\pgfmath@@operand%
      \fi
    \else%
      \expandafter\pgfmath@function@@@@process\expandafter{\pgfmath@@operand}%
    \fi%
  \fi%    
}

\def\pgfmath@function@@@@process{\csname pgfmath\pgfmath@@function @\endcsname}

% Stack.
%
\newtoks\pgfmath@stack@operand
\newtoks\pgfmath@stack@operation
\let\pgfmath@stack@empty=\pgfmath@empty

\def\pgfmath@stack@push#1#2{%
  \def\pgfmath@stack@top{#2}%
  \expandafter\expandafter\expandafter#1%
    \expandafter\expandafter\expandafter{\expandafter\expandafter\expandafter%
      {\expandafter\pgfmath@stack@top\expandafter}\the#1}}%

\def\pgfmath@stack@pop#1#2{\expandafter\pgfmath@stack@@pop\the#1\pgfmath@stack@stop{#1}{#2}}
\def\pgfmath@stack@@pop#1#2#3\pgfmath@stack@stop#4#5{\def#5{#1}#4={{#2}#3}\def\pgfmath@stack@top{#2}}

\def\pgfmath@stack@push@operation#1{%
  \pgfmath@stack@push\pgfmath@stack@operation{#1}%
  \let\pgfmath@stack@operation@top=\pgfmath@stack@top}

\def\pgfmath@stack@pop@operation#1{%
  \pgfmath@stack@pop\pgfmath@stack@operation{#1}%
  \let\pgfmath@stack@operation@top=\pgfmath@stack@top}
  
% REMARK: This method will be overwritten by the FPU library. Please
% keep any changes consistent.
\def\pgfmath@stack@push@operand#1{%
  \pgfmath@stack@push\pgfmath@stack@operand{#1}%
  \let\pgfmath@stack@operand@top=\pgfmath@stack@top}

\def\pgfmath@stack@pop@operand#1{%
  \pgfmath@stack@pop\pgfmath@stack@operand{#1}%
  \let\pgfmath@stack@operand@top=\pgfmath@stack@top}
  

% Declare an operator for the parser.
%
% It is not recommended that new operators be created as 
% the parser is not fully robust for arbitrary operators.
%
\def\pgfmathdeclareoperator#1#2#3#4#5{%
  \ifx\pgfmath@operatorlist\pgfutil@empty
    \edef\pgfmath@operatorlist{{\string#1}}%
  \else
    \edef\pgfmath@operatorlist{\pgfmath@operatorlist,{\string#1}}%
  \fi
  \pgfmath@namedef{pgfmath@operator@\string#1}{#1}%
  \pgfmath@namedef{pgfmath@operation@\string#1@name}{#2}%
  \pgfmath@namedef{pgfmath@operation@\string#1@arity}{#3}%
  \pgfmath@namedef{pgfmath@operation@\string#1@#4}{#1}%
  \pgfmath@namedef{pgfmath@operation@\string#1@precedence}{#5}%
}

\def\pgfmath@operatorlist{}

\pgfmathdeclareoperator{+}{add}     {2}{infix}{500}
\pgfmathdeclareoperator{-}{subtract}{2}{infix}{500}
\pgfmathdeclareoperator{*}{multiply}{2}{infix}{700}
\pgfmathdeclareoperator{/}{divide}  {2}{infix}{700}
\pgfmathdeclareoperator{^}{pow}     {2}{infix}{900}

\pgfmathdeclareoperator{<} {}       {1}{prefix} {1}

\pgfmathdeclareoperator{>} {greater}   {2}{infix} {250}
\pgfmathdeclareoperator{<} {less}      {2}{infix} {250}
\pgfmathdeclareoperator{==}{equal}     {2}{infix} {250}
\pgfmathdeclareoperator{>=}{notless}   {2}{infix} {250}
\pgfmathdeclareoperator{<=}{notgreater}{2}{infix} {250}
\pgfmathdeclareoperator{&&}{and}       {2}{infix} {200}
\pgfmathdeclareoperator{||}{or}        {2}{infix} {200}
\pgfmathdeclareoperator{!=}{notequal}  {2}{infix} {250}
\pgfmathdeclareoperator{!} {not}       {1}{prefix}{975}
\pgfmathdeclareoperator{?} {ifthenelse}{3}{infix} {100}
\pgfmathdeclareoperator{:} {@@collect}  {2}{infix}{101}

\pgfmathdeclareoperator{!}{factorial}{1}{postfix}{800}% Must be defined after prefix ! operator.
\pgfmathdeclareoperator{r}{deg}      {1}{postfix}{600}

\pgfmathdeclareoperator{,}{@collect}   {2}{infix}  {10}
\pgfmathdeclareoperator{[}{@startindex}{2}{prefix} {7}
\pgfmathdeclareoperator{]}{@endindex}  {0}{postfix}{6}
\pgfmathdeclareoperator{(}{@startgroup}{1}{prefix} {5}
\pgfmathdeclareoperator{)}{@endgroup}  {0}{postfix}{4}

\pgfmathdeclareoperator{\pgfmath@bgroup}{@startarray}{1}{prefix} {3}
\pgfmathdeclareoperator{\pgfmath@egroup}{@endarray}  {1}{postfix}{2}% 

% Special operators.
\pgfmathdeclareoperator{"}{}{1}{prefix}{1}
\pgfmathdeclareoperator{@}{}{0}{postfix}{0}

% Internal functions.

% Begin and end parenthesis ().
%
\def\pgfmath@startgroup@#1{\edef\pgfmathresult{#1}}
\def\pgfmath@endgroup@{}% Never actually called.

% Begin and end array access [].
%
\def\pgfmath@startindex@#1#2{%
  \expandafter\pgfmatharray@#1{#2}%
  \expandafter\pgfmath@bgroup@strip\expandafter{\pgfmathresult}%
  \ifx\pgfmath@token@let\bgroup%
    \expandafter\def\expandafter\pgfmathresult\expandafter{\expandafter{\pgfmathresult}}%
  \fi}
\def\pgfmath@endindex@{}% Never actually called.

% Begin and end array {}.
%
\def\pgfmath@startarray@#1{\expandafter\def\expandafter\pgfmathresult\expandafter{\expandafter{#1}}}
\def\pgfmath@endarray@#1{\expandafter\def\expandafter\pgfmathresult\expandafter{#1}}% Never actually called.


\def\pgfmath@@collect@#1#2{%
  \expandafter\expandafter\expandafter\def\expandafter\expandafter\expandafter%
    \pgfmathresult\expandafter\expandafter\expandafter{\expandafter\expandafter\expandafter%
      {\expandafter#1\expandafter}\expandafter{#2}}%
}
% Collect items separated by ,.
%
\def\pgfmath@collect@#1#2{%
  \expandafter\def\expandafter\pgfmath@collect@original\expandafter{#1}%
  \expandafter\pgfmath@bgroup@strip\expandafter{#1}%
  \ifx\pgfmath@token@let\bgroup%
    \ifx\pgfmath@collect@original\pgfmath@bgroup@stripped%
      \expandafter\def\expandafter\pgfmathresult\expandafter{\pgfmath@bgroup@stripped}%
    \else%
      \expandafter\def\expandafter\pgfmathresult\expandafter{\expandafter{\pgfmath@bgroup@stripped}}%
    \fi%
  \else%
    \expandafter\def\expandafter\pgfmathresult\expandafter{\expandafter{\pgfmath@bgroup@stripped}}%
  \fi%
  \expandafter\pgfmath@bgroup@strip\expandafter{#2}%
  \expandafter\expandafter\expandafter\def\expandafter\expandafter\expandafter%
    \pgfmathresult\expandafter\expandafter\expandafter%
      {\expandafter\pgfmathresult\expandafter{\pgfmath@bgroup@stripped}}%
}

% Strip braces from a token sequence.
%
\def\pgfmath@bgroup@strip#1{%
  \def\pgfmath@bgroup@strip@last{#1}%
  \pgfmath@bgroup@@strip{#1}\pgfmath@\pgfmath@@\pgfmath@@@}

\def\pgfmath@bgroup@strip@#1{%
  \def\pgfmath@bgroup@strip@last{#1}%
  \pgfmath@bgroup@@strip#1\pgfmath@\pgfmath@@\pgfmath@@@}

\def\pgfmath@bgroup@pgfmath@{\pgfmath@}

\def\pgfmath@bgroup@@strip{%
  \futurelet\pgfmath@token@let\pgfmath@bgroup@@@strip}

\def\pgfmath@bgroup@@@strip#1#2#3\pgfmath@@@{%
  \ifx\pgfmath@token@let\bgroup
    \def\pgfmath@bgroup@test{#2}%
    \ifx\pgfmath@bgroup@test\pgfmath@bgroup@pgfmath@
      \def\pgfmath@next{\pgfmath@bgroup@strip@{#1}}%
    \else
      \let\pgfmath@bgroup@stripped=\pgfmath@bgroup@strip@last
      \let\pgfmath@next=\relax
    \fi
  \else
    \pgfmath@bgroup@@@@strip#1#2#3%
    \let\pgfmath@next=\relax
  \fi
  \pgfmath@next}

\def\pgfmath@bgroup@@@@strip#1\pgfmath@\pgfmath@@{%
  \def\pgfmath@bgroup@stripped{#1}}

% Local Variables:
% tab-width: 2
% End:
