diff options
author | Karl Berry <karl@freefriends.org> | 2010-10-29 00:31:31 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2010-10-29 00:31:31 +0000 |
commit | 6bc1f5497cfb2f56d65c80a4c36ea3bad6dc046c (patch) | |
tree | f7751da75030fb1e06653eeb44e579fcee09c65f /Master/texmf-dist/tex/generic/pgf/math/pgfmathparser.code.tex | |
parent | ed0c7c756e441b2d2ba3633da233fc24361ac0d3 (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.tex | 1532 |
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}}% |