summaryrefslogtreecommitdiff
path: root/macros/latex/contrib/lisp-on-tex/lisp-arith.sty
blob: 1e4f622dbe151899a21647dc7a148be7bcd5b42b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
\newcount\@temp@inti
\newcount\@temp@intii

\@lisp@env@add@global\+{\@tlabel@func{\@lisp@func@check@args{*}{\@temp@inti0\relax\@arith@plus}}}
\def\@arith@plus#1#2#3{%
  \ifx#2\relax
    \let\@next@plus\@@arith@pm@fin
  \else\ifx#2\@tlabel@int
    \advance\@temp@inti#3\relax
    \let\@next@plus\@arith@plus
  \else
    \let\@next@plus\@arith@type@error
  \fi\fi\@next@plus#1}

\@lisp@env@add@global\*{\@tlabel@func{\@lisp@func@check@args{*}{\@temp@inti1\relax\@arith@mul}}}
\def\@arith@mul#1#2#3{%
  \ifx#2\relax
    \let\@next@mul\@@arith@pm@fin
  \else\ifx#2\@tlabel@int
    \multiply\@temp@inti#3\relax
    \let\@next@mul\@arith@mul
  \else
    \let\@next@mul\@arith@type@error
  \fi\fi\@next@mul#1}

\def\@@arith@pm@fin#1{\expandafter\gdef
  \expandafter#1\expandafter{%
  \expandafter\@tlabel@int\expandafter{\the\@temp@inti}}}

\def\@arith@type@error#1#2\relax{% notice #2 is dust
  \gdef#1{\@tlabel@exception{{-1}%
    {\@tlabel@string{arithmetical functions takes integer only.}}}}}

\@lisp@env@add@global\-{\@tlabel@func{\@lisp@func@check@args{+}{\@arith@minus}}}
%TODO: error handling of 1st argument
\def\@arith@minus#1#2#3#4#5{%
  \@temp@inti#3\relax
  \ifx#4\relax
    \multiply\@temp@inti-1\relax
    \let\@next@minus\@@arith@pm@fin
  \else\ifx#4\@tlabel@int
    \let\@next@minus\@@arith@minus
  \else
    \let\@next@minus\@arith@type@error
  \fi\fi\@next@minus#1#4{#5}}

\def\@@arith@minus#1#2#3{%
  \ifx#2\relax
    \let\@next@minus\@@arith@pm@fin
  \else\ifx#2\@tlabel@int
    \@temp@intii#3\relax % #3 < 0
    \advance\@temp@inti-\@temp@intii\relax
    \let\@next@minus\@@arith@minus
  \else
    \let\@next@minus\@arith@type@error
  \fi\fi\@next@minus#1}


\@lisp@env@add@global\/{\@tlabel@func{\@lisp@func@check@args{+}{\@arith@div}}}
%TODO: error handling of 1st argument
\def\@arith@div#1#2#3#4#5{%
  \@temp@inti#3\relax
  \ifx#4\relax
    \@temp@intii\@temp@inti\relax
    \@temp@inti1\relax
    \divide\@temp@inti\@temp@intii\relax
    \let\@next@div\@@arith@pm@fin
  \else\ifx#4\@tlabel@int
    \let\@next@div\@@arith@div
  \else
    \let\@next@div\@arith@type@error
  \fi\fi\@next@div#1#4{#5}}

\def\@@arith@div#1#2#3{%
  \ifx#2\relax
    \let\@next@div\@@arith@pm@fin
  \else\ifx#2\@tlabel@int
    \divide\@temp@inti#3\relax
    \let\@next@div\@@arith@div
  \else
    \let\@next@div\@arith@type@error
  \fi\fi\@next@div#1}

\@lisp@env@add@global\mod{\@tlabel@func{\@lisp@func@check@args{2}{\@arith@mod}}}
%TODO: error handling
\def\@arith@mod#1\@tlabel@int#2\@tlabel@int#3{%
  \@temp@intii#2\relax
  \divide\@temp@intii#3\relax
  \multiply\@temp@intii#3\relax
  \@temp@inti#2\relax
  \advance\@temp@inti-\@temp@intii
  \@@arith@pm@fin#1}

\@lisp@env@add@global\<{\@tlabel@func{\@lisp@func@check@args{2}{\@arith@lt}}}
%TODO: error handling
\def\@arith@lt#1\@tlabel@int#2\@tlabel@int#3{%
  \ifnum#2<#3 \gdef#1{\@tlabel@bool{t}}\else\gdef#1{\@tlabel@bool{f}}\fi}

\@lisp@env@add@global\>{\@tlabel@func{\@lisp@func@check@args{2}{\@arith@gt}}}
%TODO: error handling
\def\@arith@gt#1\@tlabel@int#2\@tlabel@int#3{%
  \ifnum#2>#3 \gdef#1{\@tlabel@bool{t}}\else\gdef#1{\@tlabel@bool{f}}\fi}

\@lisp@env@add@global\leq{\@tlabel@func{\@lisp@func@check@args{2}{\@arith@leq}}}
%TODO: error handling
\def\@arith@leq#1\@tlabel@int#2\@tlabel@int#3{%
  \ifnum#2<#3 \gdef#1{\@tlabel@bool{t}}\else\gdef#1{\@tlabel@bool{f}}\fi
  \ifnum#2=#3 \gdef#1{\@tlabel@bool{t}}\fi}

\@lisp@env@add@global\geq{\@tlabel@func{\@lisp@func@check@args{2}{\@arith@geq}}}
%TODO: error handling
\def\@arith@geq#1\@tlabel@int#2\@tlabel@int#3{%
  \ifnum#2>#3 \gdef#1{\@tlabel@bool{t}}\else\gdef#1{\@tlabel@bool{f}}\fi
  \ifnum#2=#3 \gdef#1{\@tlabel@bool{t}}\fi}

\@lisp@env@add@global\isZeroQ{\@tlabel@func{\@lisp@func@check@args{1}{\@arith@is@zero}}}
%TODO: error handling
\def\@arith@is@zero#1\@tlabel@int#2{%
  \ifnum#2=0 \gdef#1{\@tlabel@bool{t}}\else\gdef#1{\@tlabel@bool{f}}\fi}

\@lisp@env@add@global\positiveQ{\@tlabel@func{\@lisp@func@check@args{1}{\@arith@is@positive}}}
%TODO: error handling
\def\@arith@is@positive#1\@tlabel@int#2{%
  \ifnum#2>0 \gdef#1{\@tlabel@bool{t}}\else\gdef#1{\@tlabel@bool{f}}\fi}

\@lisp@env@add@global\negativeQ{\@tlabel@func{\@lisp@func@check@args{1}{\@arith@is@negative}}}
%TODO: error handling
\def\@arith@is@negative#1\@tlabel@int#2{%
  \ifnum#2<0 \gdef#1{\@tlabel@bool{t}}\else\gdef#1{\@tlabel@bool{f}}\fi}

\@lisp@env@add@global\max{\@tlabel@func{\@lisp@func@check@args{+}{\@arith@max}}}
\def\@arith@max#1#2#3{%
  \ifx#2\@tlabel@int
    \@temp@inti#3\relax
    \let\@next@max\@@arith@max
  \else
    \let\@next@max\@arith@type@error
  \fi\@next@max#1}
\def\@@arith@max#1#2#3{%
  \ifx#2\relax
    \let\@next@max\@@arith@pm@fin
  \else\ifx#2\@tlabel@int
    \ifnum#3>\@temp@inti\@temp@inti#3\relax\fi
    \let\@next@max\@@arith@max
  \else
    \let\@next@max\@arith@type@error
  \fi\fi\@next@max#1}

\@lisp@env@add@global\min{\@tlabel@func{\@lisp@func@check@args{+}{\@arith@min}}}
\def\@arith@min#1#2#3{%
  \ifx#2\@tlabel@int
    \@temp@inti#3\relax
    \let\@next@min\@@arith@min
  \else
    \let\@next@min\@arith@type@error
  \fi\@next@min#1}
\def\@@arith@min#1#2#3{%
  \ifx#2\relax
    \let\@next@min\@@arith@pm@fin
  \else\ifx#2\@tlabel@int
    \ifnum#3<\@temp@inti\@temp@inti#3\relax\fi
    \let\@next@min\@@arith@min
  \else
    \let\@next@min\@arith@type@error
  \fi\fi\@next@min#1}