summaryrefslogtreecommitdiff
path: root/support/splint/tex/xarithm.sty
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
committerNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
commite0c6872cf40896c7be36b11dcc744620f10adf1d (patch)
tree60335e10d2f4354b0674ec22d7b53f0f8abee672 /support/splint/tex/xarithm.sty
Initial commit
Diffstat (limited to 'support/splint/tex/xarithm.sty')
-rw-r--r--support/splint/tex/xarithm.sty317
1 files changed, 317 insertions, 0 deletions
diff --git a/support/splint/tex/xarithm.sty b/support/splint/tex/xarithm.sty
new file mode 100644
index 0000000000..4d424a863c
--- /dev/null
+++ b/support/splint/tex/xarithm.sty
@@ -0,0 +1,317 @@
+% Copyright 2014, Alexander Shibakov
+% This file is part of SPLinT
+%
+% SPLinT is free software: you can redistribute it and/or modify
+% it under the terms of the GNU General Public License as published by
+% the Free Software Foundation, either version 3 of the License, or
+% (at your option) any later version.
+%
+% SPLinT is distributed in the hope that it will be useful,
+% but WITHOUT ANY WARRANTY; without even the implied warranty of
+% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+% GNU General Public License for more details.
+%
+% You should have received a copy of the GNU General Public License
+% along with SPLinT. If not, see <http://www.gnu.org/licenses/>.
+
+% a minimum of expandable arithmetic to implement a few macros in yyparse.sty and flex.sty
+% the goal of these macros was not implementing a complete
+% integer arithmetic but rather providing the minimal functionality
+% where such arithmetic is required.
+% there are a few instances in which the utility of such arithmetic is
+% beneficial:
+% o whenever an `expession macro' should behave like a number (i.e. be
+% useful in a \number context); see \YYSTART implementation for an
+% example
+% o whenever the use of a register is to be avoided in iterative
+% macros and replaced by a `tail parameter' (see \yyless for a hint
+% of such a use)
+% o whenever \TeX's number size limitations are inadequate
+%
+% the last situation has not been a concern for this package while the
+% other two were.
+%
+% `expandable' may have different meanings. in the context of
+% arithmetic, expansion within \edef context, `prefix expansion' or
+% \number or \romannumeral0 context expansion may all be valid
+% targets. the preferred way seems to be the \romannumeral0
+% interface. the disadvantage of this method is that each macro needs
+% to produce a space at the end of its `expansion cycle', the
+% advantage is the ability to carry the extension for arbitrarily
+% large numbers (unlike, say, the \number interface). the macros below
+% are implemented so that the \expandafter\expandafter `prefix'
+% expansion and \number both work, even though internally, the
+% \romannumeral0 approach is taken. this is done to present a cleaner
+% use pattern to the consumer of the macros.
+%
+% for a complete implementation of expandable arithmetic (including
+% floating point), see the corresponding parts of the
+% \LaTeX\ project. it was decided against using that implementation to
+% avoid creating dependencies.
+
+% temporary definition, to avoid using reserved counters
+
+\edef\xxcarry{\count3=\the\count3\count\z@\the\count\z@\count\@ne\the\count\@ne}
+
+% digit extractor, used as part of several macros below.
+
+\count\z@\z@
+\bloop
+ \edef\next{\def\csname digit\number\count\z@\endcsname##1\number\count\z@##2##3.{##2}}\next %
+\ifnum9>\count\z@
+ \advance\count\z@\@ne
+\repeat
+
+% multiplication tables:
+% \xmultby?#1 expands into a pair ab which is a product of ? and #1
+
+\count\z@\z@
+\bloop{%
+ \count\@ne\z@
+ \let\next\empty
+ \bloop
+ \count3\count\z@
+ \multiply\count3\count\@ne
+ \edef\next{\next\number\count\@ne{\ifnum9<\count3 \else0\fi\number\count3}}%
+ \ifnum9>\count\@ne
+ \advance\count\@ne\@ne
+ \repeat
+ \edef\next{\def\csname xmultby\number\count\z@\endcsname##1{\noexpand\csname digit##1\noexpand\endcsname\next.}}\next
+\ifnum9>\count\z@
+ \advance\count\z@\@ne
+}\repeat
+
+% addition tables:
+% \xaddto?#1 expands into a pair ab which is a sum of ? and #1
+
+\count\z@\z@
+\bloop{%
+ \count\@ne\z@
+ \let\next\empty
+ \bloop
+ \count3\count\z@
+ \advance\count3\count\@ne
+ \edef\next{\next\number\count\@ne{\ifnum9<\count3 \else0\fi\number\count3}}%
+ \ifnum9>\count\@ne
+ \advance\count\@ne\@ne
+ \repeat
+ \edef\next{\def\csname xaddto\number\count\z@\endcsname##1{\noexpand\csname digit##1\noexpand\endcsname\next.}}\next
+\ifnum9>\count\z@
+ \advance\count\z@\@ne
+}\repeat
+
+% division tables:
+% \xdivby?#1 expands into #1 div ?
+
+\count\z@\@ne
+\bloop{%
+ \count\@ne\z@
+ \let\next\empty
+ \bloop
+ \count3\count\@ne
+ \divide\count3\count\z@
+ \edef\next{\next\number\count\@ne{\number\count3}}%
+ \ifnum9>\count\@ne
+ \advance\count\@ne\@ne
+ \repeat
+ \edef\next{\def\csname xdivby\number\count\z@\endcsname##1{\noexpand\csname digit##1\noexpand\endcsname\next.}}\next
+\ifnum9>\count\z@
+ \advance\count\z@\@ne
+}\repeat
+
+\xxcarry % restore registers
+
+% #1\times #2 + #3
+
+\def\xxcarry#1#2#3{%
+ \expandafter\x@carry\number1\csname xmultby#1\endcsname#2#3%
+}
+
+% #1 is a bogus parameter, so that a leading 0 is not dropped by \number
+
+\def\x@carry#1#2#3#4{%
+ \expandafter\x@@arry\number1\csname xaddto#3\endcsname#4#2%
+}
+
+\def\x@@arry#1#2#3#4{%
+ \ifnum#2>\z@\number\csname xaddto#2\endcsname#4\else#4\fi#3%
+}
+
+% most macros internally consume the digits from left to right.
+
+\def\xreverse#1{%
+ \romannumeral0\xr@verse{}#1.%
+}
+
+\def\xr@verse#1#2{%
+ \if#2.%
+ \yybreak{ #1}%
+ \else
+ \yybreak{\xr@verse{#2#1}}%
+ \yycontinue
+}
+
+% multiplication by 0-9
+% #1 is the number
+% #2 is the digit
+% expands to #1 * #2 in reverse digid order
+
+\def\xmultiplybydigit#1#2{%
+ \romannumeral0\xbydigit{#2}{0}{}#1.%
+}
+
+% #1 is the digit
+% #2 is the carry
+% #3 is the result
+% #4 is the next digit of the big factor
+
+\def\xbydigit#1#2#3#4{%
+ \if#4.%
+ \yybreak{\ifnum#2=\z@\xskiptofi{ #3}\else\xskiptofi{ #3#2}\fi}%
+ \else
+ \yybreak{\expandafter\xb@digit\number1#1\xxcarry#1#4#2 {#3}}%
+ \yycontinue
+}
+
+% #1 is a bogus parameter (see above)
+% #2 is the digit
+% #3 is the carry
+% #4 is the next digit of the result
+% #5 is the result up to now
+
+\def\xb@digit#1#2#3#4#5{%
+ \xbydigit#2#3{#5#4}%
+}
+
+% a version of the macros above that perform the reversion to save an
+% extra step
+
+% #1 is the digit
+% #2 is the carry
+% #3 is the result
+% #4 is the next digit of the big factor
+
+\def\xbytigid#1#2#3#4{%
+ \if#4.%
+ \yybreak{\ifnum#2=\z@\xskiptofi{ #3}\else\xskiptofi{ #2#3}\fi}%
+ \else
+ \yybreak{\expandafter\xb@tigid\number1#1\xxcarry#1#4#2 {#3}}%
+ \yycontinue
+}
+
+% #1 is a bogus parameter (see above)
+% #2 is the digit
+% #3 is the carry
+% #4 is the next digit of the result
+% #5 is the result up to now
+
+\def\xb@tigid#1#2#3#4#5{%
+ \xbytigid#2#3{#4#5}%
+}
+
+% similar to \xmultiply by digit above by produces the result in the
+% usual digit order
+
+\def\xsmallmultiple#1#2{%
+ \romannumeral0\expandafter\xsm@llmultiple\expandafter{\romannumeral0\xr@verse{}#1.}#2%
+}
+
+\def\xsm@llmultiple#1#2{%
+ \xbytigid{#2}{0}{}#1.%
+}
+
+% division by 2
+
+\def\xdivbytwo#1{%
+ \romannumeral0\expandafter\xdivbytw@\romannumeral0\xr@verse{}#1..%
+}
+
+\def\xdivbytw@#1#2{%
+ \if#2.%
+ \yybreak{\expandafter\space\number\csname xdivby2\endcsname#1}%
+ \else
+ \yybreak{\expandafter\xdivb@tw@\expandafter{\number\csname xdivby2\endcsname#1}#2}%
+ \yycontinue
+}
+
+\def\xdivb@tw@#1{%
+ \xbytigid{5}{#1}{}%
+}
+
+% increment by 1
+
+\def\xincrement#1{%
+ \romannumeral0\expandafter\x@ncrement\expandafter{\romannumeral0\xr@verse{}#1.}%
+}
+
+\def\x@ncrement#1{%
+ \x@ncr@ment{1}{}#1.%
+}
+
+% #1 is the carry
+% #2 is the result
+% #3 is the next digit of the operand
+
+\def\x@ncr@ment#1#2#3{%
+ \if#3.%
+ \yybreak{\ifnum#1=\z@\xskiptofi{ #2}\else\xskiptofi{ #1#2}\fi}%
+ \else
+ \yybreak{\ifnum#1=\z@\xskiptofi{\x@@cr@m@nt{#3#2}}\else
+ \xskiptofi{\expandafter\x@ncr@m@nt\number1\csname xaddto#1\endcsname#3{#2}}\fi}%
+ \yycontinue
+}
+
+\def\x@ncr@m@nt#1#2#3#4{%
+ \x@ncr@ment#2{#3#4}%
+}
+
+\def\x@@cr@m@nt#1#2.{%
+ \xr@verse{}#2.#1%
+}
+
+% decimal complements table
+
+\def\xcplof#1{\ifcase#1 \or9\or8\or7\or6\or5\or4\or3\or2\or1\fi}
+
+% single digit decrement by 1 table
+
+\def\xdecof#1{\ifcase#1 \or0\or1\or2\or3\or4\or5\or6\or7\or8\fi}
+
+% decrement by 1
+
+\def\xdecrement#1{%
+ \romannumeral0\expandafter\xd@crement\expandafter{\romannumeral0\xr@verse{}#1.}%
+}
+
+\def\xd@crement#1{%
+ \xd@cr@ment1{}#1.%
+}
+
+% #1 is the carry
+% #2 is the result
+% #3 is the next digit of the operand
+
+\def\xd@cr@ment#1#2#3{%
+ \if#3.%
+ \yybreak{ -1}%
+ \else
+ \yybreak{\ifnum#1=\z@
+ \xskiptofi{\xde@@@m@nt{#3#2}}%
+ \else
+ \xskiptofi{%
+ \ifnum#3=\z@
+ \xskiptofi{\xd@cr@ment1{9#2}}%
+ \else
+ \xskiptofi{\expandafter\xde@@@m@nt\expandafter{\number\xdecof#3 #2}}%
+ \fi}%
+ \fi}%
+ \yycontinue
+}
+
+\def\xd@cr@m@nt#1#2#3{%
+ \xd@cr@ment#1{#2#3}%
+}
+
+\def\xde@@@m@nt#1#2.{%
+ \xr@verse{}#2.#1%
+}