summaryrefslogtreecommitdiff
path: root/macros/latex/contrib/lisp-on-tex/lisp-prim.sty
blob: 4f921612d83154a096e06a154abdd2e9bfc4a58a (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
166
167
168
169
170
171
172
173
174
175
176
%% Syntax functions
\@lisp@env@add@global\quote{\@tlabel@quote{}}%
\@lisp@env@add@global\lambda{\@tlabel@lambda{}}
\@lisp@env@add@global\define{\@tlabel@define{}}
\@lisp@env@add@global\lispif{\@tlabel@if{}}
\@lisp@env@add@global\defmacro{\@tlabel@defmacro{}}
\@lisp@env@add@global\begin{\@tlabel@begin{}}
\@lisp@env@add@global\defineM{\@tlabel@mdefine{}}
\@lisp@env@add@global\setB{\@tlabel@setb{}}
\@lisp@env@add@global\@let{\@tlabel@@let{}}
\@lisp@env@add@global\@mlet{\@tlabel@@mlet{}}
\@lisp@env@add@global\macroexpand{\@tlabel@macroexpand{}}
\@lisp@env@add@global\callOCC{\@tlabel@callocc{}}

\@lisp@env@add@global\car{\@tlabel@func{\@lisp@func@check@args{1}{\@lisp@perform@car}}}
\@lisp@env@add@global\cdr{\@tlabel@func{\@lisp@func@check@args{1}{\@lisp@perform@cdr}}}
\@lisp@env@add@global\cons{\@tlabel@func{\@lisp@func@check@args{2}{\@lisp@perform@cons}}}

\newcount\@temp@count
\@lisp@env@add@global\length{\@tlabel@func{\@lisp@func@check@args{1}{\@lisp@length}}}
\def\@lisp@length{\@temp@count0\relax\@lisp@length@}
\def\@lisp@length@#1#2#3{%
  \ifx#2\@tlabel@nil
    \expandafter\gdef\expandafter#1%
    \expandafter{\expandafter\@tlabel@int\expandafter{\the\@temp@count}}%
    \let\@length@next\@length@gobble
  \else\ifx#2\@tlabel@cons
    \advance\@temp@count1\relax
    \let\@length@next\@@lisp@length
  \else
    \errmessage{LISP on TeX [function--length]: The Argument must be a LIST}%
  \fi\fi\@length@next#3#1}
\def\@length@gobble#1{}
\def\@@lisp@length#1#2#3{\expandafter\@lisp@length@\expandafter#3#2}

%equality
\@lisp@env@add@global\={\@tlabel@func{\@lisp@func@check@args{2}{\@lisp@equal}}}
\def\@lisp@equal#1#2#3#4#5{%
  \gdef#1{\@tlabel@bool{f}}%
  \ifx#2#4%
    \def\@@temp@eqchecki{#3}%
    \def\@@temp@eqcheckii{#5}%
    \ifx\@@temp@eqchecki\@@temp@eqcheckii\gdef#1{\@tlabel@bool{t}}\fi
  \fi}

% printing function
\@lisp@env@add@global\print{\@tlabel@func{\@lisp@func@check@args{1}{\@tex@print}}}
\def\@tex@print#1{\gdef#1{\@tlabel@nil{}}\@tex@print@}
\def\@tex@print@#1#2{%
  \ifx#1\@tlabel@int
    \@add@to@write@buffer\@temp@write@buffer{:#2}%
  \else\ifx#1\@tlabel@symbol
    \@add@to@write@buffer\@temp@write@buffer{\string#2}%
  \else\ifx#1\@tlabel@string
    \@add@to@write@buffer\@temp@write@buffer{'#2'}%
  \else\ifx#1\@tlabel@bool
    \@add@to@write@buffer\@temp@write@buffer{/#2}%
  \else\ifx#1\@tlabel@dimen
    \@add@to@write@buffer\@temp@write@buffer{!#2}%
  \else\ifx#1\@tlabel@skip
    \@add@to@write@buffer\@temp@write@buffer{@#2}%
  \else\ifx#1\@tlabel@nil
    \@add@to@write@buffer\@temp@write@buffer{()}%
  \else\ifx#1\@tlabel@cons
    \@add@to@write@buffer\@temp@write@buffer{(}%
    \@tex@print@cell#2%
  \else
    \@add@to@write@buffer\@temp@write@buffer{[INNER]}%
  \fi\fi\fi\fi\fi\fi\fi\fi}
\def\@tex@print@cell#1#2{%
  \expandafter\@tex@print@#1%
  \expandafter\@tex@print@cdr#2}
\def\@tex@print@cdr#1#2{%
  \ifx#1\@tlabel@cons
    \@add@to@write@buffer\@temp@write@buffer{ }%
    \@tex@print@cell#2%
  \else\ifx#1\@tlabel@nil
    \@add@to@write@buffer\@temp@write@buffer{)}%
  \else
    \@add@to@write@buffer\@temp@write@buffer{.}%
    \@tex@print@#1{#2}%
    \@add@to@write@buffer\@temp@write@buffer{)}%
  \fi\fi}



\@lisp@env@add@global\texprint{\@tlabel@func{\@lisp@func@check@args{1}{\@tex@texprint}}}
\def\@tex@texprint#1#2#3{%
   \gdef#1{\@tlabel@nil{}}\@@tex@texprint#2{#3}}
\def\@@tex@texprint#1#2{%
  \ifx#1\@tlabel@string
    \@add@to@write@buffer\@temp@write@buffer{#2}%
  \else\ifx#1\@tlabel@int
    \@add@to@write@buffer\@temp@write@buffer{#2}%
  \else
    \@add@to@write@buffer\@temp@write@buffer{INNER TOKEN}%
  \fi\fi}

\@lisp@env@add@global\stdprint{\@tlabel@func{\@lisp@func@check@args{1}{\@tex@stdprint}}}
\def\@tex@stdprint#1#2#3{%
  \gdef#1{\@tlabel@nil{}}%
  \let\@save@write@buffer\@temp@write@buffer
  \def\@temp@write@buffer{}%
  \@tex@print@#2{#3}%
  \toks0\expandafter{\@temp@write@buffer}%
  \immediate\write16{\the\toks0}%
  \let\@temp@write@buffer\@save@write@buffer}


% Type predicates
\def\@type@pred@add#1{\expandafter\@@type@pred@add\expandafter#1}
\def\@@type@pred@add#1#2{\@lisp@env@add@global#1{\@tlabel@func{\@lisp@func@check@args{1}{#2}}}}
\def\@type@pred@define#1{\expandafter\@@type@pred@define\expandafter#1}
\def\@@type@pred@define#1#2{%
	\def#1##1##2##3{\ifx##2#2\gdef##1{\@tlabel@bool{t}}\else\gdef##1{\@tlabel@bool{f}}\fi}}

\@for\@lisp@on@tex@type:=\@defined@datatype\do{%
  \expandafter\@type@pred@add\csname\@lisp@on@tex@type Q\endcsname
      \csname @type@\@lisp@on@tex@type\endcsname
  \expandafter\@type@pred@define\csname @type@\@lisp@on@tex@type\endcsname\csname @tlabel@\@lisp@on@tex@type\endcsname}

\@lisp@env@add@global\pairQ{\@tlabel@func{\@type@cons}}
\@lisp@env@add@global\booleanQ{\@tlabel@func{\@type@bool}}

% eval , apply
\@lisp@env@add@global\eval{\@tlabel@envfunc{\@extern@eval}}
\def\@extern@eval#1#2#3#4{\@eval#3{#4}{#2}#1}
\@lisp@env@add@global\apply{\@tlabel@envfunc{\@extern@apply}}
\def\@extern@apply#1#2#3#4#5#6{% reg, env, labelfun, contfun, labellist, contlist
  \def\@lisp@apply@temp{}% init
  \@flatten@args#5{#6}\@lisp@apply@temp
  \expandafter\@extern@apply@next\expandafter{\@lisp@apply@temp}#3{#4}{#2}#1}
\def\@extern@apply@next#1#2#3#4#5{% arglist-flatten, labelfun, contfun env, reg
  {\expandafter\@@select@@apply#2{#3}#1\@{#4}#5}}

% values
%\@lisp@env@add@global\values{\@tlabel@func{\@lisp@multivalues}}
%\def\@lisp@multivalues#1#2\relax{\gdef#1{#2}}

% read
\@lisp@env@add@global\read{\@tlabel@func{\@lisp@func@check@args{0}{\@lisp@read@stdin}}}
\def\@lisp@read@stdin#1{%
  \read-1 to#1%
  \def\@lisp@read@stdin@callback##1##2{%
    \gdef#1{##1{##2}}}%
  \expandafter\@lispread\expandafter\@lisp@read@stdin@callback#1}

% create a list
\@lisp@env@add@global\list{\@tlabel@func{\@lisp@func@check@args{*}{\@lisp@prim@list@pre}}}
\def\@lisp@prim@list@pre#1{\gdef#1{}\@lisp@prim@list#1}
\def\@lisp@prim@list#1#2#3{%
  \ifx#2\relax
    \let\@@next\@lisp@prim@list@fin
  \else
    \let\@@next\@lisp@prim@list@add
  \fi\@@next#1#2{#3}}
\def\@lisp@prim@list@add#1#2#3{%
  \begingroup
    \toks0\expandafter{#1}%
    \toks1{#2{#3}}%
    \xdef#1{\the\toks1 \the\toks0}%reverse arguments
  \endgroup
  \@lisp@prim@list#1}
\def\@lisp@prim@list@fin#1#2#3{\expandafter\@lisp@prim@list@fin@\expandafter#1#1\relax\relax}
\def\@lisp@prim@list@fin@#1{%
  \gdef#1{\@tlabel@nil{}}%
  \@lisp@prim@list@fin@@#1}
\def\@lisp@prim@list@fin@@#1#2#3{%
  \ifx#2\relax
    \def\@@next##1##2##3{}%
  \else
    \let\@@next\@lisp@prim@list@fin@@@
  \fi
  \@@next#1#2{#3}}
\def\@lisp@prim@list@fin@@@#1#2#3{\expandafter\@lisp@prim@list@fin@@@@#1#2{#3}#1}
\def\@lisp@prim@list@fin@@@@#1#2#3#4#5{\@lisp@perform@cons#5#3{#4}#1{#2}\@lisp@prim@list@fin@@#5}