summaryrefslogtreecommitdiff
path: root/macros/latex/contrib/lisp-on-tex/lisp-read.sty
blob: bcfb7fd4fa14c48dd8c2e04dbf8bd355f4a73ef1 (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
%%
%% This is file `lisp-read.sty'.
%%
%%  License: Modified BSD - see LICENSE file
%%

%% End Of Input(EOI)
\def\@end@lispread{\@@end@lispread}

%% Reader Macro
%% @param #1 callback function (which gets a S-exp and do something)
%% @param #2 the first letter of the input or EOI
%% @return #1\@tlabel@xxx{contents}
\def\@lispread#1#2{\begingroup\@lispread@main#1#2}

%% The first branch
%% @param #1 callback function
%% @param #2 the first letter of the input or EOI
\def\@lispread@main#1#2{% Define \@@next, the continuation. 
  \if\noexpand#2(% [Branch 1] CONS cell or NIL
    \def\@@next{\@lispread@cell#1}%
  \else\ifcat\noexpand#2\relax% [Branch 2] A control sequence or a control symbol 
    \ifx#2\@end@lispread % [Branch 2-1] EOI
      \def\@@next{\endgroup#1%
        \@tlabel@exception{{-1}{\@tlabel@string{!Found End of Input!}}}}%
    \else
      \def\@@next{\@lispread@symbol#1#2}% [Branch 2-2] Symbol
    \fi
  \else\if\noexpand#2'% [Branch 3] String
      \def\@@next{\@lispread@string#1\@lispread@string@dummy}% 
  \else\if\noexpand#2/% [Branch 4] Boolean
    \def\@@next{\@lispread@bool#1}%
  \else\if\noexpand#2:% [Branch 5] Integer
    \def\@@next{\@lispread@int#1}%
  \else\if\noexpand#2!% [Branch 6] Dimension 
    \def\@@next{\@lispread@dimen#1}%
  \else\if\noexpand#2@% [Branch 7] Skip
    \def\@@next{\@lispread@skip#1}%
  \else\if\noexpand#2+% [Branch 8] call a Reader Module 
    \def\@@next{\@lispread@module#1}%
  \else % Otherwise -- parse error
    \errmessage{LISP on teX [read]: no such type start with \noexpand#2}%
  \fi\fi\fi\fi\fi\fi\fi\fi
  \@@next}
%% Symbol 
\def\@lispread@symbol#1#2{%
  \endgroup#1\@tlabel@symbol{#2}}
%% String
\def\@lispread@string@dummy{}   % to avoid consuming group
\def\@lispread@string#1#2'{%
  \endgroup\expandafter#1\expandafter\@tlabel@string\expandafter{#2}}
%% Boolean
\def\@lispread@bool#1#2{%
  \endgroup#1\@tlabel@bool{#2}}
%% Reader Module
\def\@lispread@module#1#2{%
  \@lispread@module@main\@register@lispread@module#2\@@end
  \endgroup
  \expandafter#1\@register@lispread@module}
\def\@lispread@module@main#1#2::#3\@@end{\csname @mod@read@#2\endcsname#1{#3}}
%% Integer
\newcount\@cnt@lispread@int
\def\@lispread@int#1{%
  \gdef\@lispread@int@callback{\@lispread@int@main#1}%
  \afterassignment\@lispread@int@callback
  \global\@cnt@lispread@int}
\def\@lispread@int@main#1{%
  \endgroup\expandafter#1\expandafter\@tlabel@int\expandafter{\the\@cnt@lispread@int}}
%% Skip
\newskip\@cnt@lispread@skip
\def\@lispread@skip#1{%
  \gdef\@lispread@skip@callback{\@lispread@skip@main#1}%
  \afterassignment\@lispread@skip@callback
  \global\@cnt@lispread@skip}
\def\@lispread@skip@main#1{%
  \endgroup\expandafter#1\expandafter\@tlabel@skip\expandafter{\the\@cnt@lispread@skip}}
%% Dimen
\newdimen\@cnt@lispread@dimen
\def\@lispread@dimen#1{%
  \gdef\@lispread@dimen@callback{\@lispread@dimen@main#1}%
  \afterassignment\@lispread@dimen@callback
  \global\@cnt@lispread@dimen}
\def\@lispread@dimen@main#1{%
  \endgroup\expandafter#1\expandafter\@tlabel@dimen\expandafter{\the\@cnt@lispread@dimen}}
%% CONS cell or NIL
\def\@lispread@cell#1#2{%
  \if\noexpand#2)% [Branch 1] NIL
    \def\@@next{\endgroup#1\@tlabel@nil{}}%
  \else % Otherwise CONS cell
    \def\@@next{\@lispread@cell@car#1#2}%
  \fi\@@next}
%% first part of CONS cell : read CAR
\def\@lispread@cell@car#1{%
  \def\@lispread@car@reg##1##2{%
    \def\@reg@lispread@car{##1{##2}}%
    \@lispread@cell@dot#1}%
  \@lispread\@lispread@car@reg}
\def\@lispread@cell@dot#1#2{%
  \if\noexpand#2.%
    \def\@@next{%
      \def\@lispread@cell@fincheck####1####2{%
        \def\@reg@lispread@cdr{####1{####2}}%
        \@lispread@fin#1}%
    \@lispread\@lispread@cell@fincheck}% kokonaosu
  \else
    \def\@@next{\@lispread@cell@cdr#1(#2}%
  \fi\@@next}
\def\@lispread@cell@cdr#1{%
  \def\@lispread@cdr@reg##1##2{%
    \expandafter\@lisp@perform@cons@local\expandafter\@reg@tmp\@reg@lispread@car##1{##2}%
    \expandafter\endgroup\expandafter#1\@reg@tmp}%
  \@lispread\@lispread@cdr@reg}
\def\@lispread@fin#1#2{%
  \if\noexpand#2)%
    \def\@@next{%
      \expandafter\expandafter\expandafter\@lisp@perform@cons@local
      \expandafter\expandafter\expandafter\@reg@tmp
      \expandafter\@reg@lispread@car\@reg@lispread@cdr
      \expandafter\endgroup\expandafter#1\@reg@tmp}%
  \else
    \def\@@next{\errmessage{LISP on teX [read]: missing )}}%
  \fi\@@next}