summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex/generic/pgf/math/pgfmathparser.code.tex
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2010-10-29 00:31:31 +0000
committerKarl Berry <karl@freefriends.org>2010-10-29 00:31:31 +0000
commit6bc1f5497cfb2f56d65c80a4c36ea3bad6dc046c (patch)
treef7751da75030fb1e06653eeb44e579fcee09c65f /Master/texmf-dist/tex/generic/pgf/math/pgfmathparser.code.tex
parented0c7c756e441b2d2ba3633da233fc24361ac0d3 (diff)
pgf 2.10 (28oct10)
git-svn-id: svn://tug.org/texlive/trunk@20236 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/tex/generic/pgf/math/pgfmathparser.code.tex')
-rw-r--r--Master/texmf-dist/tex/generic/pgf/math/pgfmathparser.code.tex1532
1 files changed, 667 insertions, 865 deletions
diff --git a/Master/texmf-dist/tex/generic/pgf/math/pgfmathparser.code.tex b/Master/texmf-dist/tex/generic/pgf/math/pgfmathparser.code.tex
index 3d69d34b73c..81f6545897e 100644
--- a/Master/texmf-dist/tex/generic/pgf/math/pgfmathparser.code.tex
+++ b/Master/texmf-dist/tex/generic/pgf/math/pgfmathparser.code.tex
@@ -1,970 +1,772 @@
-% Copyright 2007 Mark Wibrow
-%
-% This file may be distributed and/or modified
-%
-% 1. under the LaTeX Project Public License and/or
-% 2. under the GNU Public License.
-%
-% See the file doc/generic/pgf/licenses/LICENSE for more details.
-% This file parses/evaluates a decimal expression.
-%
-% Version 1.414213 29/9/2007
+\newdimen\pgfmath@dimen
+\newcount\pgfmath@count
+\newbox\pgfmath@box
+\newtoks\pgfmath@toks
-% \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
+\newif\ifpgfmathfloat
+\newif\ifpgfmathunitsdeclared
+\newif\ifpgfmathignoreunitscale
+
+\def\pgfmathprint#1{\pgfmathparse{#1}\pgfmathresult}
\def\pgfmathparse{%
- \pgfmath@quickparsefalse%
- \pgfmathparse@}
+ \begingroup%
+ \pgfmath@catcodes%
+ \pgfmath@quickparsefalse%
+ \ifpgfmathfloat%
+ \let\pgfmath@parse@next=\pgfmathfloatparsenumber%
+ \else%
+ \let\pgfmath@parse@next=\pgfmathparse@%
+ \fi%
+ \pgfmath@parse@next}
-\def\pgfmathqparse{%
- \pgfmath@quickparsetrue%
- \pgfmathparse@}
-
-\def\pgfmath@calcreal#1{#1}%
-\def\pgfmath@calcminof#1#2{min(#1,#2)}%
-\def\pgfmath@calcmaxof#1#2{max(#1,#2)}%
-\def\pgfmath@calcratio#1#2{#1/#2}%
+\def\pgfmath@catcodes{% Maybe unecessary.
+ \catcode`\==12%
+ \catcode`\,=12%
+ \catcode`\|=12%
+ \catcode`\&=12%
+}
+\def\pgfmathqparse{%
+ \begingroup%
+ \pgfmath@catcodes%
+ \pgfmath@quickparsetrue%
+ \pgfmathparse@}
+
\def\pgfmathparse@#1{%
- \begingroup%
- % Reinstall correct font, so that dimensions like 1em are correct
+ % 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.
\pgfmath@selectfont%
- \let\real\pgfmath@calcreal%
- \let\minof\pgfmath@calcminof%
- \let\maxof\pgfmath@calcmaxof%
- \let\ratio\pgfmath@calcratio%
- \edef\pgfmath@temp{#1}%
- \pgfmath@resetparsingparameters%
+ % Expand expression so any reamining CSs are registers
+ % or box dimensions (i.e., \wd, \ht, \dp).
+ \edef\pgfmath@expression{#1}%
+ % No units yet.
\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}
+ % 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}%
+ \expandafter\pgfmath@parse@@operand\pgfmath@bgroup@stripped @@@@\pgfmath@parse@stop%
+}%
+\def\pgfmath@parse@end#1\pgfmath@parse@stop{%
+ \pgfmathpostparse%
+ \pgfmath@smuggleone\pgfmathresult%
+ \endgroup%
+ \ignorespaces}%
-% \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.
+\let\pgfmathpostparse=\relax%
+
+% For compatiability with older version.
%
-\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%
+\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%
}
-
-% 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%
- \ignorespaces%
-}
+% 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{%
+ \def\pgfmath@prefix{#1}%
+ \expandafter\pgfmath@tokens@@make#2{}}
+
+\def\pgfmath@tokens@@make#1{%
+ \def\pgfmath@token{#1}%
+ \ifx\pgfmath@token\pgfmath@empty%
+ \else%
+ \pgfmath@namedef{pgfmath@token@\pgfmath@prefix @\string#1}{#1}%
+ \expandafter\pgfmath@tokens@@make%
+ \fi}
-% \pgfmath@startparsegroup
-%
-% When opening ( is scanned start a new group.
+\pgfmath@tokens@make{box}{\wd\ht\dp}
+\pgfmath@tokens@make{unit}{{bp}{cc}{cm}{dd}{em}{ex}{in}{mm}{pc}{pt}{sp}}
+\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.
%
-\def\pgfmath@startparsegroup{%
+\newif\ifpgfmath@dimen@
+\def\pgfmath@dimen@#1{%
\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%
+ \afterassignment\pgfmath@dimen@@%
+ #1=0.0pt\relax\pgfmath@}
+\def\pgfmath@dimen@@#1#2\pgfmath@{%
\endgroup%
- \pgfmath@parsepostgroup%
-}
+ \ifx#1.%
+ \pgfmath@dimen@false%
+ \else%
+ \pgfmath@dimen@true%
+ \fi}
-% \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%
+\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%
- \ifx#1+%
- \let\pgfmath@parsenext\pgfmath@parseadd%
+ \ifx\pgfmath@token@let\pgfmath@sptoken%
+ \let\pgfmath@parse@next=\pgfmath@parse@@@@ifbgroup%
\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
+ \let\pgfmath@parse@next=\pgfmath@parse@nobgroup@after%
+ \fi%
+ \fi%
+ \pgfmath@parse@next}
-% \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.
+\def\pgfmath@parse@@@ifbgroup#1{\pgfmath@parse@bgroup@after\pgfmath@bgroup#1\pgfmath@egroup}
-% \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}%
+{
+\def\:{\pgfmath@parse@@@@ifbgroup}
+\expandafter\gdef\: {\futurelet\pgfmath@token@let\pgfmath@parse@@ifbgroup}
}
-% \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}%
+% Parse an operand.
+%
+\def\pgfmath@parse@operand{\expandafter\pgfmath@parse@@operand\pgfmath@token@next}%
-% \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}}%
+\def\pgfmath@parse@@operand{\pgfmath@parse@ifbgroup{\pgfmath@parse@@operand}{\pgfmath@parse@@operand@}}
-% \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}%
+\def\pgfmath@parse@@operand@#1{%
+ \def\pgfmath@token{#1}%
+ \ifx\pgfmath@token\pgfmath@char@plus% Ignore.
+ \let\pgfmath@parse@next=\pgfmath@parse@@operand%
\else%
- \ifx\pgfmath@empty#2\relax%
- \pgfmath@stack{{#1}\pgfmath@empty\pgfmath@empty\pgfmath@empty\pgfmath@empty}%
+ \ifx\pgfmath@token\pgfmath@char@minus%
+ \pgfmath@stack@push@operation{neg}% Unary minus.
+ \let\pgfmath@parse@next=\pgfmath@parse@@operand%
\else%
- #2{#3}{#1}%
- \pgfmath@stack{#4#5}%
- \expandafter\pgfmath@stackpushoperand\expandafter{\pgfmathresult}%
- \fi\fi%
- \def\pgfmath@stacknextoperator{#4}}
+ \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.
+ \def\pgfmath@base{8}%
+ \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%
+}
-% \pgfmath@processalloperations
-%
-% Process all operation in the stack. The
-% overall result is at the top of the stack.
+% Parse prefix operators.
%
-\def\pgfmath@processalloperations{%
- \expandafter\pgfmath@in@\pgfmath@stacknextoperator{\pgfmath@empty}%
- \ifpgfmath@in@%
- \let\pgfmath@processnext\relax%
+\def\pgfmath@parse@prefix@operator{%
+ \ifx\pgfmath@token\pgfmath@char@quote% Quote character.
+ \let\pgfmath@parse@next=\pgfmath@parse@operand@quote%
\else%
- \pgfmath@stackpopoperation%
- \let\pgfmath@processnext\pgfmath@processalloperations%
+ \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@processnext}
+ \pgfmath@parse@next%
+}%
-% \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\pgfmath@in@\pgfmath@stacknextoperator{#1\pgfmath@empty}%
- \ifpgfmath@in@%
- \let\pgfmath@processnext\pgfmath@processoperationsuntil@end%
+
+% 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%
- \pgfmath@stackpopoperation%
- \let\pgfmath@processnext\pgfmath@processoperationsuntil%
+ \expandafter\ifcat\pgfmath@token\relax% A CS?
+ \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%
+ \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%
+ % ...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 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@processnext{#1}}
-\def\pgfmath@processoperationsuntil@end#1{}
+ \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%
+}
-% OK. Now the operators are parsed.
-% These correspond to the + - / * ^ < > = operators and r (postfix) function.
+% Parse binary or hexadecimal numbers (octal numbers done elsehwere).
%
-\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%
+\def\pgfmath@parse@base{%
+ \ifnum\pgfmath@base=2\relax%
+ \let\pgfmath@parse@next=\pgfmath@parse@binary%
\else%
- % Empty the process stack up to any inequalities.
- \pgfmath@processoperationsuntil{\pgfmathequalto@\pgfmathlessthan@\pgfmathgreaterthan@}%
+ \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%
- \pgfmath@stackpushoperator{\pgfmathadd@}%
- \pgfmath@parse@}
+ \let\pgfmath@number=\pgfmath@empty%
+ \expandafter\pgfmath@parse@next\pgfmath@token@next%
+}
-\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%
+\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%
- % Empty the process stack up to any inequalities.
- \pgfmath@processoperationsuntil{\pgfmathequalto@\pgfmathlessthan@\pgfmathgreaterthan@}%
+ \expandafter\def\expandafter\pgfmath@number\expandafter{\pgfmath@number#1}%
+ \let\pgfmath@parse@next=\pgfmath@parse@binary%
\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%
+ \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%
- % Process all operations up to inequalites or addition/subtraction
- \pgfmath@processoperationsuntil{\pgfmathequalto@\pgfmathlessthan@\pgfmathgreaterthan@%
- \pgfmathadd@\pgfmathsubtract@}%
+ \expandafter\def\expandafter\pgfmath@number\expandafter{\pgfmath@number#1}%
+ \let\pgfmath@parse@next=\pgfmath@parse@hexadecimal%
\fi%
- \pgfmath@stackpushoperator{\pgfmathmultiply@}%
- \pgfmath@parse@}
+ \pgfmath@parse@next%
+}
-\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%
+% 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%
- % Process all operations up to inequalites or addition/subtraction
- \pgfmath@processoperationsuntil{\pgfmathequalto@\pgfmathlessthan@\pgfmathgreaterthan@%
- \pgfmathadd@\pgfmathsubtract@}%
+ \let\pgfmath@parse@next=\pgfmath@parse@@@function%
\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{%
- % r 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@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}
-% \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@
- % Gobble multiple signs.
- \edef\pgfmath@sign{\pgfmath@sign#1}%
- \expandafter\pgfmath@parseoperandsign%
+\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\pgfmath@parsenumberorfunction\expandafter#1%
+ \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%
}
-\newif\ifpgfmath@dimen@
-\def\pgfmath@ifregisterdimen@#1\pgfmath@{%
- \pgfmath@in@{p}{#1}%
- \ifpgfmath@in@%
- \pgfmath@dimen@true%
+% Process an operation.
+%
+\def\pgfmath@operation@process#1{%
+ \def\pgfmath@operator{#1}%
+ \ifx\pgfmath@stack@operation@top\pgfmath@stack@empty%
\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=\pgfmath@sign#1#2%
- \edef\pgfmathresult{\pgfmath@tonumber{\pgfmath@parsex}}%
- \global\pgfmathunitsdeclaredtrue% a dimension has units
- \pgfmath@parseoperator%
+ \pgfmath@operation@@process%
+ \fi%
+ \expandafter\ifx\csname pgfmath@token@specials@#1\endcsname\relax%
+ \pgfmath@stack@push@operation{#1}%
+ \fi%
}
-\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%
+% 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%
- % 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%
+ \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%
- \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{%
- \ifx#1(% It might be a group e.g. -(1+2)...
- \let\pgfmath@parsenext\pgfmath@parseoperandgroup%
+ \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%
- \pgfmath@in@{#1}{.0123456789}%
- \ifpgfmath@in@% ... or a number...
- \let\pgfmath@parsenext\pgfmath@parsenumber%
- \else% ... or a function.
- \let\pgfmath@parsenext\pgfmath@parsefunction%
- \fi%
+ % No operators with more than tenary arity.
\fi%
- \pgfmath@parsenext#1%
-}%
-
-\def\pgfmath@parseoperandgroup({%
- \let\pgfmath@postparsegroup\pgfmath@@parseoperandgroup%
- \pgfmath@startparsegroup%
-}
-
-\def\pgfmath@@parseoperandgroup{%
- \let\pgfmath@postparsegroup\pgfmath@parseoperator%
- \edef\pgfmathresult{\pgfmath@sign\pgfmathresult}%
- \pgfmath@parseoperator%
}
-\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}
-
-
+\def\pgfmath@operator@@@@process{%
+ \csname pgfmath%
+ \csname pgfmath@operation@\pgfmath@@operator @name\endcsname%
+ @\endcsname}
-% 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.
+% Process a function.
%
-% 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{%
- \pgfmath@ifnextchar\relax%
- {%
- % Ok, this is a looong mantisse. Start gobbling all following
- % numbers
- \pgfmath@gobblemantisse%
- }%
- {%
- \pgfmath@removeguard%
- }%
+\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@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@function@@@@process{\csname pgfmath\pgfmath@@function @\endcsname}
-\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%
-}
+% Stack.
+%
+\newtoks\pgfmath@stack@operand
+\newtoks\pgfmath@stack@operation
+\let\pgfmath@stack@empty=\pgfmath@empty
-\def\pgfmath@parseunits@boxdimen#1#2{%
- \pgfmath@parsex=\pgfmath@sign#1#2%
- \pgfmath@parsex\pgfmath@resulttemp\pgfmath@parsex%
- \edef\pgfmathresult{\pgfmath@tonumber{\pgfmath@parsex}}%
- \global\pgfmathunitsdeclaredtrue% a dimension has units
- \pgfmath@parseoperator%
-}
+\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@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@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@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%
-}
+\def\pgfmath@stack@push@operation#1{%
+ \pgfmath@stack@push\pgfmath@stack@operation{#1}%
+ \let\pgfmath@stack@operation@top=\pgfmath@stack@top}
-% 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@}
-
-% Functions parsed (not calculated) 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).
-% ln(X) logarithm of X.
-% pow(X,Y) X^Y,
-%
-% 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\pgfmath@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@stack@pop@operation#1{%
+ \pgfmath@stack@pop\pgfmath@stack@operation{#1}%
+ \let\pgfmath@stack@operation@top=\pgfmath@stack@top}
-\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}
+% 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}
-% \pgfmath@parsefunction@abs
+% Declare an operator for the parser.
%
-\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
+% It is not recommended that new operators be created as
+% the parser is not fully robust for arbitrary operators.
%
-\def\pgfmath@parsefunction@sqrt{%
- \let\pgfmath@parsepostgroup\pgfmath@parsefunction@sqrt@%
- \expandafter\pgfmath@parse@}
-\def\pgfmath@parsefunction@sqrt@{%
- \expandafter\pgfmathsqrt@\expandafter{\pgfmathresult}%
- \pgfmath@postfunction%
+\def\pgfmathdeclareoperator#1#2#3#4#5{%
+ \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}%
}
-% \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%
-}
+\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}
-% \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%
-}
+\pgfmathdeclareoperator{<} {} {1}{prefix} {1}
-% \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%
-}
+\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{!=}{notequalto}{2}{infix} {250}
+\pgfmathdeclareoperator{!} {not} {1}{prefix}{975}
+\pgfmathdeclareoperator{?} {ifthenelse}{3}{infix} {100}
+\pgfmathdeclareoperator{:} {@@collect} {2}{infix}{101}
-% \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%
-}
+\pgfmathdeclareoperator{!}{factorial}{1}{postfix}{800}% Must be defined after prefix ! operator.
+\pgfmathdeclareoperator{r}{deg} {1}{postfix}{600}
-% \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%
-}
+\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}
-% \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%
-}
+\pgfmathdeclareoperator{\pgfmath@bgroup}{@startarray}{1}{prefix} {3}
+\pgfmathdeclareoperator{\pgfmath@egroup}{@endarray} {1}{postfix}{2}%
-% \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%
-}
+% Special operators.
+\pgfmathdeclareoperator{"}{}{1}{prefix}{1}
+\pgfmathdeclareoperator{@}{}{0}{postfix}{0}
-% \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%
-}
+% Internal functions.
-% \pgfmath@parsefunction@cot
+% Begin and end parenthesis ().
%
-\def\pgfmath@parsefunction@cot{%
- \let\pgfmath@parsepostgroup\pgfmath@parsefunction@cot@%
- \expandafter\pgfmath@parse@}
-\def\pgfmath@parsefunction@cot@{%
- \expandafter\pgfmathcot@\expandafter{\pgfmathresult}%
- \pgfmath@postfunction%
-}
+\def\pgfmath@startgroup@#1{\edef\pgfmathresult{#1}}
+\def\pgfmath@endgroup@{}% Never actually called.
-% \pgfmath@parsefunction@sec
+% Begin and end array access [].
%
-\def\pgfmath@parsefunction@sec{%
- \let\pgfmath@parsepostgroup\pgfmath@parsefunction@sec@%
- \expandafter\pgfmath@parse@}
-\def\pgfmath@parsefunction@sec@{%
- \expandafter\pgfmathsec@\expandafter{\pgfmathresult}%
- \pgfmath@postfunction%
-}
+\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.
-% \pgfmath@parsefunction@cosec
+% Begin and end array {}.
%
-\def\pgfmath@parsefunction@cosec{%
- \let\pgfmath@parsepostgroup\pgfmath@parsefunction@cosec@%
- \expandafter\pgfmath@parse@}
-\def\pgfmath@parsefunction@cosec@{%
- \expandafter\pgfmathcosec@\expandafter{\pgfmathresult}%
- \pgfmath@postfunction%
-}
+\def\pgfmath@startarray@#1{\expandafter\def\expandafter\pgfmathresult\expandafter{\expandafter{#1}}}
+\def\pgfmath@endarray@#1{\expandafter\def\expandafter\pgfmathresult\expandafter{#1}}% Never actually called.
-% \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@ln
-%
-\def\pgfmath@parsefunction@ln{%
- \let\pgfmath@parsepostgroup\pgfmath@parsefunction@ln@%
- \expandafter\pgfmath@parse@}
-\def\pgfmath@parsefunction@ln@{%
- \expandafter\pgfmathln@\expandafter{\pgfmathresult}%
- \pgfmath@postfunction%
+\def\pgfmath@@collect@#1#2{%
+ \expandafter\expandafter\expandafter\def\expandafter\expandafter\expandafter%
+ \pgfmathresult\expandafter\expandafter\expandafter{\expandafter\expandafter\expandafter%
+ {\expandafter#1\expandafter}\expandafter{#2}}%
}
-
-% \pgfmath@parsefunction@pi
+% Collect items separated by ,.
%
-\def\pgfmath@parsefunction@pi{%
- \pgfmathpi%
- \pgfmath@postfunction%
+\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}}%
}
-% \pgfmath@parsefunction@veclen
+% Strip braces from a token sequence.
%
-\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} \ No newline at end of file
+\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}}%