\def\yquant@register@type@none{0} \def\yquant@register@type@q{1} \def\yquant@register@type@c{2} \def\yquant@register@type@qs{3} \def\yquant@register@type@tostring#1{% \ifcase#1 % nobit% \or% qubit% \or% cbit% \or% qubits% \else% \PackageError{yquant.sty}{Internal inconsistency detected}% {Unknown wire type: `#1'.}% \fi% } \protected\def\yquant@register@type@fromstring#1#2{% \expandafter\ifstrequal\expandafter{#1}{qubit}% {\let#2=\yquant@register@type@q}% {% \expandafter\ifstrequal\expandafter{#1}{cbit}% {\let#2=\yquant@register@type@c}% {% \expandafter\ifstrequal\expandafter{#1}{qubits}% {\let#2=\yquant@register@type@qs}% {% \PackageError{yquant.sty}{Invalid bit type: `#1'}% {Use one of `qubit', `cbit', or `qubits'.}% }% }% }% } % Internally, we store the register information in a single macro. Indeed, this is almost always faster than using multiple macros (at least in the way implemented here), apart from changing a single type of information, which is almost as fast. % BEGIN_FOLD Constructor: create single register and cleanup environment % #1: type % #2: x position % #3: name % #4: index \protected\def\yquant@register@define#1#2#3#4{% \csnumgdef{\yquant@prefix registers}% {\csname\yquant@prefix registers\endcsname+1}% \csxdef{\yquant@prefix register@\csname\yquant@prefix registers\endcsname}{% {#1}% type {#2}% x pos {{\the\dimexpr.5\dimexpr\yquant@config@register@minimum@height\relax\relax}% {\the\dimexpr.5\dimexpr\yquant@config@register@minimum@height\relax\relax}}% height and depth; at the end, the y position {{\yquant@env@create@x}{\yquant@env@create@x}{}{}}% wire start positions and clipping {}% wire style }% \global\csletcs{\yquant@prefix registername@#3[#4]}{\yquant@prefix registers}% \csxdef{\yquant@prefix registerhigh@#3}{#4}% \yquant@cleanup@csadd{\yquant@prefix register@\csname\yquant@prefix registers\endcsname}% \yquant@cleanup@csadd{\yquant@prefix registername@#3[#4]}% \ifnum0=#4\relax% \yquant@cleanup@csadd{\yquant@prefix registerhigh@#3}% \fi% } % in a subcircuit, create a new register that is only an alias for an existing register in the outer circuit. % #5: id in the outer circuit \protected\def\yquant@register@alias#1#2#3#4#5{% \csnumgdef{\yquant@prefix registers}% {\csname\yquant@prefix registers\endcsname+1}% \ifcsname\yquant@parent registermap@#5\endcsname% % the parent is already an alias itself, pass this on transparently \global\csletcs% {\yquant@prefix registermap@\csname\yquant@prefix registers\endcsname}% {\yquant@parent registermap@#5}% \else% \csxdef{\yquant@prefix registermap@\csname\yquant@prefix registers\endcsname}% {\yquant@parent register@#5}% \fi% % even though this is an alias, we still need to keep track of its internal dimensions \csgdef{\yquant@prefix registerdim@\csname\yquant@prefix registers\endcsname}% {{0pt}{0pt}}% \yquant@cleanup@csadd{\yquant@prefix registerdim@\csname\yquant@prefix registers\endcsname}% \global\csletcs{\yquant@prefix registername@#3[#4]}{\yquant@prefix registers}% \csxdef{\yquant@prefix registerhigh@#3}{#4}% \yquant@cleanup@csadd{\yquant@prefix registermap@\csname\yquant@prefix registers\endcsname}% \yquant@cleanup@csadd{\yquant@prefix registername@#3[#4]}% \ifnum0=#4\relax% \yquant@cleanup@csadd{\yquant@prefix registerhigh@#3}% \fi% \csxdef{\yquant@prefix lastinput}{{\csname\yquant@prefix registers\endcsname}{#5}}% \unless\ifcsname\yquant@prefix firstinput\endcsname% \csxdef{\yquant@prefix firstinput}{{\csname\yquant@prefix registers\endcsname}{#5}}% \yquant@cleanup@csadd{\yquant@prefix firstinput}% \yquant@cleanup@csadd{\yquant@prefix lastinput}% \fi% \expandafter\yquant@register@set@@aux% \csname\csname\yquant@prefix registermap@\csname\yquant@prefix registers\endcsname\endcsname\endcsname% \yquant@register@set@x@aux% {#2}% } % END_FOLD % BEGIN_FOLD Converter: convert a register name to its id % store the number corresponding to register #2 into #1 \protected\def\yquant@register@get@id#1#2{% \ifcsname\yquant@prefix registername@#2\endcsname% \letcs#1{\yquant@prefix registername@#2}% \else% \yquant@register@get@id@lazycreate{#2}% \letcs#1{\yquant@prefix registers}% \fi% } % same as before, but resolves to the _index_ of the last register \protected\def\yquant@register@get@id@high#1#2{% \unless\ifcsname\yquant@prefix registerhigh@#2\endcsname% \yquant@register@get@id@lazycreate{#2}% \fi% \letcs#1{\yquant@prefix registerhigh@#2}% } % In the lazy mode, we create all unknown registers on-the-fly. \def\yquant@register@get@id@lazycreate#1{% \ifyquant@env@lazy% % In principle, we could just call \yquant@lang@@qubit. However, if access to a vector register is desired and a _part_ of this does already exist (though not the requested index), we only create the missing registers. \yquant@register@get@id@lazycreate@parse#1[;% \else% \PackageError{yquant.sty}{Register `#1' unknown}% {You referred to an unknown register. Declare registers first using `qubit' and friends.}% \fi% } \def\yquant@register@get@id@lazycreate@parse#1[#2;{% \ifstrempty{#2}{% \yquant@register@get@id@lazycreate@do#1[0][;% }{% \yquant@register@get@id@lazycreate@do#1[#2;% }% } \protected\def\yquant@register@get@id@lazycreate@do#1[#2]#3[;{% \begingroup% % parse length \ifstrempty{#3}{% \yquant@langhelper@validate\len\count{#2}% \numdef\len{\len+1}% }{% \PackageError{yquant.sty}{Invalid register name}% {Register names must not contain `[' apart from register length indication.}% }% \edef\reg{\trim@spaces{#1}}% % Was this register already defined? \ifcsname\yquant@prefix registerhigh@\reg\endcsname% \numdef\idx{\csname\yquant@prefix registerhigh@\reg\endcsname+1}% \unless\ifnum\idx<\len\relax% \PackageError{yquant.sty}{Internal inconsistency detected}% {Tried to create a register on-the-fly that already existed.}% \fi% \else% \def\idx{0}% \fi% % pre-set y position \yquant@for \idx := \idx to \numexpr \len -1\relax {% \yquant@register@define% \yquant@register@type@q% {\yquant@env@create@x}% \reg\idx% % Prepare to shipout \csxappto{\yquant@prefix draw}{% \yquant@lang@create@draw{\csname\yquant@prefix registers\endcsname}% {0pt}% {qubit}% 0% {}% {}% }% }% \endgroup% } \newif\ifyquant@register@get@allowmulti % converts names to indices % #1: comma-separated string of names or ranges % range format: startname-endname % Both startname and endname may be omitted, denoting the very first and last % register, respectively % If \ifyquant@register@get@allowmulti is set to true, multi-qubit registers are % allowed, which are surrounded by parentheses. They may not appear in ranges. % \yquant@register@get@ids@list, \yquant@register@get@ids@min, \yquant@register@get@ids@max and \yquant@register@get@ids@count will be set appropriately \begingroup% \catcode`[=\active% \catcode`(=\active% \protected\gdef\yquant@register@get@ids#1{% \begingroup% \let\yquant@register@get@ids@list=\empty% \count0=2147483647 % minimal id \count2=0 % maximal id \count4=0 % number of total registers \ifblank{#1}{}{% \let\ifinmulti=\iffalse% \let\ifallowmain=\iffalse% \let\do=\yquant@register@get@ids@outerlist% \begingroup% \catcode`[=\active% \catcode`(=\active% \def[##1]{\yquant@register@get@ids@@index{##1}}% \def(##1){\yquant@register@get@ids@@multi{##1}}% % this is also invoked by other languages which might have completely redefined all catcodes (qasm redefines the backslash), so don't just add \noexpand at the end of the \scantokens... \everyeof{\noexpand}% \endlinechar=-1 % \edef\yquant@register@get@ids@retokenized{\scantokens{#1}}% \expandafter% \endgroup% \expandafter\docsvlist\expandafter{\yquant@register@get@ids@retokenized}% }% \global\let\yquant@register@get@ids@list=\yquant@register@get@ids@list% \xdef\yquant@register@get@ids@min{\the\count0}% \xdef\yquant@register@get@ids@max{\the\count2}% \xdef\yquant@register@get@ids@count{\the\count4}% \endgroup% } \endgroup \protected\def\yquant@register@get@ids@@index{} \protected\def\yquant@register@get@ids@@multi{} \def\yquant@register@get@ids@outerlist#1{% \ifyquant@firsttoken\yquant@register@get@ids@@multi{#1}{% \unless\ifyquant@register@get@allowmulti% \PackageError{yquant.sty}{Multi-register gate not allowed}% {The selected gate can only be used in a single-register context.}% \fi% \yquant@register@get@ids@multi#1\yquant@sep% }{% \yquant@register@get@ids@checkrange#1-\yquant@sep% }% } \protected\def\yquant@register@get@ids@multi\yquant@register@get@ids@@multi#1\yquant@sep{% \begingroup% \let\yquant@register@get@ids@list=\empty% \count0=2147483647 % minimal id \count2=0 % maximal id \count4=0 % number of total registers \count6=-1 % index of main register \let\ifinmulti=\iftrue% \let\ifallowmain=\iftrue% \let\do=\yquant@register@get@ids@multilist% \docsvlist{#1}% \ifnum\count6=-1 % \count6=\count0 % \fi% \yquant@register@multi@splitparts% \edef\process{% \endgroup% \noexpand\listadd\noexpand\yquant@register@get@ids@list{% \noexpand\yquant@register@multi% {\the\count0}{\the\count2}{\the\count4}% {\yquant@register@get@ids@list}% }% \noexpand\ifnum\count0>\the\count0\space% \count0=\the\count0\space% \noexpand\fi% \noexpand\ifnum\count2<\the\count2\space% \count2=\the\count2\space% \noexpand\fi% \advance\count4 by 1 % }% \process% } \def\yquant@register@get@ids@multilist#1{% \yquant@register@get@ids@checkrange#1-\yquant@sep% } \def\yquant@register@get@ids@checkrange#1-#2\yquant@sep{% \ifstrempty{#2}{% % the string does not contain a dash \yquant@register@get@ids@norange{#1}% }{% % this is a range argument \yquant@register@get@ids@range#1-#2\yquant@sep% }% } \def\yquant@register@get@ids@norange#1{% % the register is not used within a range, which gives us full freedom with respect to sub-index selections \yquant@register@get@ids@norange@checkindex% #1% \yquant@register@get@ids@@index% \yquant@sep% } \protected\def\yquant@register@get@ids@norange@checkindex#1\yquant@register@get@ids@@index#2\yquant@sep{% \edef\current{\trim@spaces{#1}}% \ifallowmain% \expandafter\ifyquant@firsttoken\expandafter*\expandafter{\current}{% \edef\current{% \expandafter\expandafter\expandafter\trim@spaces% \expandafter\expandafter\expandafter{% \expandafter\@gobble\current% }% }% % catch the minimal index \edef\yquant@register@get@ids@norange@checkindex@setmain{% \count6=\count2% \ifnum\count0<\the\count0 % \count0=\the\count0 % \fi% }% \count0=2147483647 % \csletcs{ifallowmain}{iffalse}% }{% \let\yquant@register@get@ids@norange@checkindex@setmain=\relax% }% \else% \let\yquant@register@get@ids@norange@checkindex@setmain=\relax% \fi% \ifstrempty{#2}{% % the string does not contain a sub-index; we add the full register \yquant@register@get@id\first{\current[0]}% \letcs\high{\yquant@prefix registerhigh@\current}% \yquant@register@get@id\last{\current[\high]}% \ifnum\first<\count0 % \count0=\first\relax% \fi% \ifnum\last>\count2 % \count2=\last\relax% \fi% \advance\count4 by \numexpr\high+1\relax% \yquant@for \i := 0 to \high {% \yquant@register@get@id\idx{\current[\i]}% \listeadd\yquant@register@get@ids@list{\idx}% }% }{% \yquant@register@get@ids@norange@index#2% }% \yquant@register@get@ids@norange@checkindex@setmain% } \protected\def\yquant@register@get@ids@norange@index#1\yquant@register@get@ids@@index{% \let\olddo=\do% % the string contains sub-indices; since we are not in a range, multi-indices may still be allowed \ifinmulti% \let\do=\yquant@register@get@ids@subindex@nomulti% \else% \let\do=\yquant@register@get@ids@subindex@allowmulti% \fi% \docsvlist{#1}% \let\do=\olddo% } \def\yquant@register@get@ids@subindex@nomulti#1{% \yquant@register@get@ids@subindex@checkrange#1-\yquant@sep% } \def\yquant@register@get@ids@subindex@allowmulti#1{% \ifyquant@firsttoken\yquant@register@get@ids@@multi{#1}{% \unless\ifyquant@register@get@allowmulti% \PackageError{yquant.sty}{Multi-register gate not allowed}% {The selected gate can only be used in a single-register context.}% \fi% \yquant@register@get@ids@subindex@multi#1\yquant@sep% }{% \yquant@register@get@ids@subindex@checkrange#1-\yquant@sep% }% } \protected\def\yquant@register@get@ids@subindex@multi\yquant@register@get@ids@@multi#1\yquant@sep{% \begingroup% \let\yquant@register@get@ids@list=\empty% \count0=2147483647 % minimal id \count2=0 % maximal id \count4=0 % number of total registers \count6=-1 % index of main register \let\ifinmulti=\iftrue% \let\ifallowmain=\iftrue% \let\do=\yquant@register@get@ids@subindex@nomulti% \docsvlist{#1}% \ifnum\count6=-1 % \count6=\count0 % \fi% \yquant@register@multi@splitparts% \edef\process{% \endgroup% \noexpand\listadd\noexpand\yquant@register@get@ids@list{% \noexpand\yquant@register@multi% {\the\count0}{\the\count2}{\the\count4}% {\yquant@register@get@ids@list}% }% \noexpand\ifnum\count0>\the\count0\space% \count0=\the\count0\space% \noexpand\fi% \noexpand\ifnum\count2<\the\count2\space% \count2=\the\count2\space% \noexpand\fi% \advance\count4 by 1 % }% \process% } \def\yquant@register@get@ids@subindex@checkrange#1-#2\yquant@sep{% \ifstrempty{#2}{% % the string does not contain a dash, this is a single sub-item \edef\idx{\trim@spaces{#1}}% \expandafter\yquant@register@get@ids@subindex@norange\expandafter{\idx}% }{% % this is a range argument \yquant@register@get@ids@subindex@range#1-#2\yquant@sep% }% } \protected\def\yquant@register@get@ids@subindex@norange#1{% \ifallowmain%% \ifyquant@firsttoken*{#1}{% \edef\idx{\current[\expandafter\trim@spaces\expandafter{\@gobble#1}]}% \expandafter\yquant@register@get@id\expandafter\idx\expandafter{\idx}% \count6=\idx% \csletcs{ifallowmain}{iffalse}% }{% \yquant@register@get@id\idx{\current[#1]}% }% \else% \yquant@register@get@id\idx{\current[#1]}% \fi% \ifnum\idx<\count0 % \count0=\idx\relax% \fi% \ifnum\idx>\count2 % \count2=\idx\relax% \fi% \advance\count4 by 1\relax% \listeadd\yquant@register@get@ids@list{\idx}% } \protected\def\yquant@register@get@ids@subindex@range#1-#2-\yquant@sep{% \ifallowmain% \ifyquant@firsttoken*{#1}{% \expandafter\ifblank\expandafter{\@gobble#1}{% \def\first{0}% }{% \expandafter\yquant@langhelper@validate\expandafter\first\expandafter\count\expandafter{\@gobble#1}% }% \yquant@register@get@id\idx{\current[\first]}% \count6=\idx% \csletcs{ifallowmain}{iffalse}% }{% \ifblank{#1}{% \def\first{0}% }{% \yquant@langhelper@validate\first\count{#1}% }% }% \else% \ifblank{#1}{% \def\first{0}% }{% \yquant@langhelper@validate\first\count{#1}% }% \fi% \ifallowmain% % in #1, all initial spaces are gobbled automatically, but not in #2 \expandafter\ifyquant@firsttoken\expandafter*\expandafter{\empty#2}{% \expandafter\ifblank\expandafter{\@gobble#2}{% \yquant@register@get@id@high\last\current% }{% \expandafter\yquant@langhelper@validate\expandafter\last\expandafter\count\expandafter{\@gobble#2}% }% \yquant@register@get@id\idx{\current[\last]}% \count6=\idx% \csletcs{ifallowmain}{iffalse}% }{% \ifblank{#2}{% \yquant@register@get@id@high\last\current% }{% \yquant@langhelper@validate\last\count{#2}% }% }% \else% \ifblank{#2}{% \yquant@register@get@id@high\last\current% }{% \yquant@langhelper@validate\last\count{#2}% }% \fi% \yquant@for \i := \first to \last {% \yquant@register@get@ids@subindex@norange\i% }% } \protected\def\yquant@register@get@ids@range#1-#2-\yquant@sep{% % being a range between two registers, those must be uniquely identifiable, i.e. either a single sub-indexed part of a vector register, or no vector specification at all. \ifallowmain% \ifyquant@firsttoken*{#1}{% \expandafter\ifblank\expandafter{\@gobble#1}{% \def\first{1}% }{% \expandafter\yquant@register@get@ids@range@getfirst\@gobble#1\yquant@register@get@ids@@index\yquant@sep% }% \count6=\first% \csletcs{ifallowmain}{iffalse}% }{% \ifblank{#1}{% \def\first{1}% }{% \yquant@register@get@ids@range@getfirst#1\yquant@register@get@ids@@index\yquant@sep% }% }% \else% \ifblank{#1}{% \def\first{1}% }{% \yquant@register@get@ids@range@getfirst#1\yquant@register@get@ids@@index\yquant@sep% }% \fi% % it does not make sense to allow to set the main part on the second half of the range, since a range over registers (not indices) is automatically visual, so this range will be contiguous. \ifblank{#2}{% \letcs\last{\yquant@prefix registers}% }{% \yquant@register@get@ids@range@getlast#2\yquant@register@get@ids@@index\yquant@sep% }% \ifnum\first<\last\relax% \ifnum\first<\count0 % \count0=\first\relax% \fi% \ifnum\last>\count2 % \count2=\last\relax% \fi% \advance\count4 by \numexpr\last-\first+1\relax% \else% \ifnum\last<\count0 % \count0=\last\relax% \fi% \ifnum\first>\count2 % \count2=\first\relax% \fi% \advance\count4 by \numexpr\first-\last+1\relax% \fi% \yquant@for \i := \first to \last {% \listeadd\yquant@register@get@ids@list{\i}% }% } \def\yquant@register@get@ids@range@getfirst#1\yquant@register@get@ids@@index#2\yquant@sep{% \ifstrempty{#2}{% \yquant@register@get@id\first{\trim@spaces{#1}[0]}% }{% \yquant@register@get@ids@range@get\first#1\yquant@register@get@ids@@index#2% }% } \protected\def\yquant@register@get@ids@range@getlast#1\yquant@register@get@ids@@index#2\yquant@sep{% \ifstrempty{#2}{% \yquant@register@get@id@high\last{\trim@spaces{#1}}% \yquant@register@get@id\last{\trim@spaces{#1}[\last]}% }{% \yquant@register@get@ids@range@get\last#1\yquant@register@get@ids@@index#2% }% } \def\yquant@register@get@ids@range@get#1#2\yquant@register@get@ids@@index#3\yquant@register@get@ids@@index{% \yquant@register@get@id#1{\trim@spaces{#2}[\trim@spaces{\trim@spaces#3}]}% } \let\yquant@register@multi=\empty% \protected\def\yquant@register@multi@contiguous{}% % splits \yquant@register@get@ids@list into a list of contiguous parts \protected\def\yquant@register@multi@splitparts{% \begingroup% \let\registers=\yquant@register@get@ids@list% \yquant@sort@list\registers\yquant@sort@ascending% \let\newlist=\empty% \count2=-1 % \def\do##1{% \ifnum\count2=-1 % \count2=##1 % \count4=\count2 % \else% \advance\count2 by 1 % \ifnum##1>\count2 % % this is a discontiguous change (we disallow duplicate entries) \eappto\newlist{% \yquant@register@multi@contiguous% {\the\count4}{\the\numexpr\count2-1\relax}% {\ifnum\count6<\count2 % \ifnum\count4>\count6 % 0% \else% 1% \fi% \else% 0% \fi}% }% \count2=##1 % \count4=\count2 % \fi% \fi% }% \dolistloop\registers% % we disallow empty lists \eappto\newlist{% \yquant@register@multi@contiguous% {\the\count4}{\the\count2}% {\ifnum\count6>\count2 % 0% \else% \ifnum\count4>\count6 % 0% \else% 1% \fi% \fi}% }% \expandafter% \endgroup% \expandafter\def\expandafter\yquant@register@get@ids@list\expandafter{% \newlist% }% } % splits \yquant@register@get@ids@list into a list of discontiguous parts \protected\def\yquant@register@multi@splitparts@sepall{% \begingroup% \let\registers=\yquant@register@get@ids@list% \yquant@sort@list\registers\yquant@sort@ascending% \let\newlist=\empty% \def\do##1{% \eappto\newlist{% \yquant@register@multi@contiguous% {##1}{##1}% {\ifnum##1=\count6 % 1% \else% 0% \fi% }% }% }% \dolistloop\registers% \expandafter% \endgroup% \expandafter\def\expandafter\yquant@register@get@ids@list\expandafter{% \newlist% }% } \protected\def\yquant@register@multi@splitparts@sort{% \yquant@sort@list\yquant@register@get@ids@list\yquant@sort@ascending% } \protected\def\yquant@register@get@multiassingle{% \yquant@register@get@allowmultitrue% \let\yquant@register@multi@splitparts=\yquant@register@multi@splitparts@sepall% \preto\yquant@attrs@remaining{/yquant/operator/multi as single,}% } \protected\def\yquant@register@get@multiaslist{% \yquant@register@get@allowmultitrue% \let\yquant@register@multi@splitparts=\yquant@register@multi@splitparts@sort% } \let\yquant@register@multi@reset@original@splitparts=\yquant@register@multi@splitparts% \protected\def\yquant@register@reset@multi{% % \yquant@register@get@allowmultifalse% not needed, as \yquant@circuit@operator automatically resets it \let\yquant@register@multi@splitparts=\yquant@register@multi@reset@original@splitparts% } % END_FOLD % BEGIN_FOLD Getters: extract the requested information from the register with given id \def\yquant@register@get@type#1{% \ifcsname\yquant@prefix registermap@#1\endcsname% \expandafter\expandafter\expandafter% \yquant@register@get@type@aux\csname\csname\yquant@prefix registermap@#1\endcsname\endcsname% \else% \expandafter\expandafter\expandafter% \yquant@register@get@type@aux\csname\yquant@prefix register@#1\endcsname% \fi% } \def\yquant@register@get@type@aux#1#2#3#4#5{#1} \def\yquant@register@get@x#1{% \ifcsname\yquant@prefix registermap@#1\endcsname% \expandafter\expandafter\expandafter% \yquant@register@get@x@aux\csname\csname\yquant@prefix registermap@#1\endcsname\endcsname% \else% \expandafter\expandafter\expandafter% \yquant@register@get@x@aux\csname\yquant@prefix register@#1\endcsname% \fi% } \def\yquant@register@get@x@aux#1#2#3#4#5{#2} \def\yquant@register@get@height#1{% \ifcsname\yquant@prefix registermap@#1\endcsname% \expandafter\expandafter\expandafter% \@firstoftwo\csname\yquant@prefix registerdim@#1\endcsname% \else% \expandafter\expandafter\expandafter% \yquant@register@get@height@aux\csname\yquant@prefix register@#1\endcsname% \fi% } \def\yquant@register@get@height@aux#1#2#3#4#5{\@firstoftwo#3} \def\yquant@register@get@depth#1{% \ifcsname\yquant@prefix registermap@#1\endcsname% \expandafter\expandafter\expandafter% \@secondoftwo\csname\yquant@prefix registerdim@#1\endcsname% \else% \expandafter\expandafter\expandafter% \yquant@register@get@depth@aux\csname\yquant@prefix register@#1\endcsname% \fi% } \def\yquant@register@get@depth@aux#1#2#3#4#5{\@secondoftwo#3} % The y parameter get macros exist in two forms: The protected one is used during the storage to the draw macro; it should never be executed. The env environment then maps them to their proper expandable forms. \protected\def\yquant@register@get@y{% \PackageError% {yquant.sty}% {Execution of a get-y macro in an illegal context}% {get-y macros may not be called unless the yquant environment ends.}% } % This plays a similar role: It must never be expanded before the tikz command is invoked (because it does not exist). \protected\def\nodepart{} \def\yquant@register@get@y@unprotected#1{% \ifcsname\yquant@prefix registermap@#1\endcsname% \expandafter\expandafter\expandafter% \yquant@register@get@y@aux\csname\csname\yquant@prefix registermap@#1\endcsname\endcsname% \else% \expandafter\expandafter\expandafter% \yquant@register@get@y@aux\csname\yquant@prefix register@#1\endcsname% \fi% } \def\yquant@register@get@y@aux#1#2#3#4#5{#3} % y distance between two registers. \def\yquant@register@get@ydist#1#2{% \expandafter\yquant@abs\expandafter% {\the\dimexpr\yquant@register@get@y{#2}-\yquant@register@get@y{#1}\relax}% } \protected\def\yquant@register@get@y@@expandable{% \let\yquant@register@get@y=\yquant@register@get@y@unprotected% } \def\yquant@register@get@lastwire#1{% \ifcsname\yquant@prefix registermap@#1\endcsname% \expandafter\@firstoftwo% \else% \expandafter\@secondoftwo% \fi% {% \expandafter\expandafter\expandafter% \yquant@register@get@lastwire@aux\csname\csname\yquant@prefix registermap@#1\endcsname\endcsname% }{% \expandafter\expandafter\expandafter% \yquant@register@get@lastwire@aux\csname\yquant@prefix register@#1\endcsname% }% } \protected\def\yquant@register@get@lastwire@aux#1#2#3#4#5#6{% \def#6{#4}% } \def\yquant@register@get@style#1{% \ifcsname\yquant@prefix registermap@#1\endcsname% \expandafter\expandafter\expandafter% \yquant@register@get@style@aux\csname\csname\yquant@prefix registermap@#1\endcsname\endcsname% \else% \expandafter\expandafter\expandafter% \yquant@register@get@style@aux\csname\yquant@prefix register@#1\endcsname% \fi% } \def\yquant@register@get@style@aux#1#2#3#4#5{#5} \def\yquant@register@get@typeywire#1{% \ifcsname\yquant@prefix registermap@#1\endcsname% \expandafter\@firstoftwo% \else% \expandafter\@secondoftwo% \fi% {% \expandafter\expandafter\expandafter% \yquant@register@get@typeywire@aux\csname\csname\yquant@prefix registermap@#1\endcsname\endcsname% }{% \expandafter\expandafter\expandafter% \yquant@register@get@typeywire@aux\csname\yquant@prefix register@#1\endcsname% }% } \protected\def\yquant@register@get@typeywire@aux#1#2#3#4#5#6#7#8{% \def#6{#1}% \def#7{#3}% \def#8{#4}% }% % Set #1 to the maximum x value found between #2 and #3 \protected\def\yquant@register@get@maxxrange#1#2#3{% \begingroup% \dimen0=-16383.99999pt % \yquant@for \yquant@register@get@maxx@i := #2 to #3 {% \dimen2=\yquant@register@get@x{\yquant@register@get@maxx@i}\relax% \ifdim\dimen0<\dimen2 % \dimen0=\dimen2 % \fi% }% \expandafter% \endgroup% \expandafter\def\expandafter#1\expandafter{\the\dimen0}% } % Set #1 to the maximum x value found in the list #2 \protected\def\yquant@register@get@maxxlist#1#2{% \begingroup% \dimen0=-16383.99999pt % \def\do##1{% \dimen2=\yquant@register@get@x{##1}\relax% \ifdim\dimen0<\dimen2 % \dimen0=\dimen2 % \fi% }% \dolistloop{#2}% \expandafter% \endgroup% \expandafter\def\expandafter#1\expandafter{\the\dimen0}% } % END_FOLD % BEGIN_FOLD Setters: change register information \protected\long\def\yquant@register@set@@aux#1#2#3{% \xdef#1{\expandafter#2#1{#3}}% } \protected\def\yquant@register@set@type#1{% \ifcsname\yquant@prefix registermap@#1\endcsname% \expandafter\@firstoftwo% \else% \expandafter\@secondoftwo% \fi% {% \expandafter\yquant@register@set@@aux% \csname\csname\yquant@prefix registermap@#1\endcsname\endcsname% }{% \expandafter\yquant@register@set@@aux% \csname\yquant@prefix register@#1\endcsname% }% \yquant@register@set@type@aux% } \long\def\yquant@register@set@type@aux#1#2#3#4#5#6{% {#6}\unexpanded{{#2}{#3}{#4}{#5}}% } \protected\def\yquant@register@set@x#1{% \ifcsname\yquant@prefix registermap@#1\endcsname% \expandafter\@firstoftwo% \else% \expandafter\@secondoftwo% \fi% {% \expandafter\yquant@register@set@@aux% \csname\csname\yquant@prefix registermap@#1\endcsname\endcsname% }{% \expandafter\yquant@register@set@@aux% \csname\yquant@prefix register@#1\endcsname% }% \yquant@register@set@x@aux% } \long\def\yquant@register@set@x@aux#1#2#3#4#5#6{% \unexpanded{{#1}}{#6}\unexpanded{{#3}{#4}{#5}}% } \protected\def\yquant@register@update@height#1#2{% \ifcsname\yquant@prefix registermap@#1\endcsname% \ifdim#2>% \expandafter\expandafter\expandafter% \@firstoftwo\csname\yquant@prefix registerdim@#1\endcsname% \relax% \csxdef{\yquant@prefix registerdim@#1}{% {#2}% {\expandafter\expandafter\expandafter% \@secondoftwo\csname\yquant@prefix registerdim@#1\endcsname}% }% \fi% \else% \ifdim#2>% \expandafter\expandafter\expandafter% \yquant@register@get@height@aux\csname\yquant@prefix register@#1\endcsname% \relax% \expandafter\yquant@register@set@@aux% \csname\yquant@prefix register@#1\endcsname% \yquant@register@set@height@aux{#2}% \fi% \fi% } \long\def\yquant@register@set@height@aux#1#2#3#4#5#6{% \unexpanded{{#1}{#2}}% {{#6}{\unexpanded\expandafter{\@secondoftwo#3}}}% \unexpanded{{#4}{#5}}% } \protected\def\yquant@register@update@depth#1#2{% \ifcsname\yquant@prefix registermap@#1\endcsname% \ifdim#2>% \expandafter\expandafter\expandafter% \@secondoftwo\csname\yquant@prefix registerdim@#1\endcsname% \relax% \csxdef{\yquant@prefix registerdim@#1}{% {\expandafter\expandafter\expandafter% \@firstoftwo\csname\yquant@prefix registerdim@#1\endcsname}% {#2}% }% \fi% \else% \ifdim#2>% \expandafter\expandafter\expandafter% \yquant@register@get@depth@aux\csname\yquant@prefix register@#1\endcsname% \relax% \expandafter\yquant@register@set@@aux% \csname\yquant@prefix register@#1\endcsname% \yquant@register@set@depth@aux{#2}% \fi% \fi% } \long\def\yquant@register@set@depth@aux#1#2#3#4#5#6{% \unexpanded{{#1}{#2}}% {{\unexpanded\expandafter{\@firstoftwo#3}}{#6}}% \unexpanded{{#4}{#5}}% } \protected\def\yquant@register@set@y#1{% \ifcsname\yquant@prefix registermap@#1\endcsname% \expandafter\@firstoftwo% \else% \expandafter\@secondoftwo% \fi% {% \expandafter\yquant@register@set@@aux% \csname\csname\yquant@prefix registermap@#1\endcsname\endcsname% }{% \expandafter\yquant@register@set@@aux% \csname\yquant@prefix register@#1\endcsname% }% \yquant@register@set@y@aux% } \long\def\yquant@register@set@y@aux#1#2#3#4#5#6{% \unexpanded{{#1}{#2}}{#6}\unexpanded{{#4}{#5}}% } \protected\def\yquant@register@set@lastwire#1{% \ifcsname\yquant@prefix registermap@#1\endcsname% \expandafter\@firstoftwo% \else% \expandafter\@secondoftwo% \fi% {% \expandafter\yquant@register@set@@aux% \csname\csname\yquant@prefix registermap@#1\endcsname\endcsname% }{% \expandafter\yquant@register@set@@aux% \csname\yquant@prefix register@#1\endcsname% }% \yquant@register@set@lastwire@aux% } \long\def\yquant@register@set@lastwire@aux#1#2#3#4#5#6{% \unexpanded{{#1}{#2}{#3}}{#6}\unexpanded{{#5}}% } \protected\def\yquant@register@set@style#1{% \ifcsname\yquant@prefix registermap@#1\endcsname% \expandafter\@firstoftwo% \else% \expandafter\@secondoftwo% \fi% {% \expandafter\yquant@register@set@@aux% \csname\csname\yquant@prefix registermap@#1\endcsname\endcsname% }{% \expandafter\yquant@register@set@@aux% \csname\yquant@prefix register@#1\endcsname% }% \yquant@register@set@style@aux% } \long\def\yquant@register@set@style@aux#1#2#3#4#5#6{% \unexpanded{{#1}{#2}{#3}{#4}}{#6}% } % END_FOLD