OSDN Git Service

e91020ae3521d6788f8650eba1bbdd4b261a5573
[simplecms/utakata.git] / src / lexer / term_checker.cpp
1 #include "src/lexer/term_checker.h"
2 #include "src/unicode.h"
3 #include "src/encoding_reader.h"
4
5 namespace term = utakata::lexer::term;
6 namespace unicode = utakata::unicode;
7 namespace reader = utakata::reader;
8
9 // 宣言のコメントを参照してください。
10 bool term::Delimiter::operator()(reader::IReader* reader,
11                                  unsigned int* size) {
12   unicode::UniChar ch(reader->Peek());
13   switch (ch.rawcode()) {
14     case '(':
15     case '[':
16     case ')':
17     case ']':
18     case '"':
19     case ';':
20     case '#':
21       *size = 1;
22       return true;
23     default:
24       return term::Whitespace()(reader, size);
25   }
26 }
27
28
29 // 宣言のコメントを参照してください。
30 bool term::Whitespace::operator()(reader::IReader* reader,
31                                          unsigned int* size) {
32   unicode::UniChar ch(reader->Peek());
33   switch (ch.rawcode()) {
34     case '\r':                  // carriage return
35     case '\n':                  // linefeed
36     case ' ':                   // space
37     case '\t':                  // tab
38     case '\v':                  // vertical tab
39     case '\f':                  // page
40       *size = 1;
41       return true;
42     default:
43       return false;
44   }
45 }
46
47 // targetが\rである場合、次の一文字のチェックも必要となりますが、
48 // \r単体である場合でも、改行として見做されます。
49 bool term::LineEnding::operator()(reader::IReader* reader,
50                                          unsigned int* size) {
51   unicode::UniChar ch(reader->Peek());
52   switch (ch.rawcode()) {
53     case '\n':
54       *size = 1;
55       return true;
56     case '\r': {
57       unicode::UniString ch2(unicode::Convert(reader->Peek(2)));
58       if (ch2.At(0).rawcode() == '\r' && ch2.At(1).rawcode() == '\n') {
59         *size = 2;
60       } else {
61         *size = 1;
62       }
63       return true;
64     }
65     default:
66       return false;
67   }
68 }
69
70 // 宣言のコメントを参照してください。
71 bool term::StringDoubleQuote::operator()(reader::IReader* reader,
72                                          unsigned int* size) {
73   unicode::UniChar ch(reader->Peek());
74   if (ch.rawcode() == '"') {
75     *size = 1;
76     return true;
77   }
78   return false;
79 }
80
81 // 宣言のコメントを参照してください。
82 bool term::HexValue::operator()(reader::IReader* reader,
83                                 unsigned int* size) {
84   unicode::UniChar ch(reader->Peek());
85   if (('a' <= ch.rawcode() && ch.rawcode() <= 'f') ||
86       ('A' <= ch.rawcode() && ch.rawcode() <= 'F') ||
87       ('0' <= ch.rawcode() && ch.rawcode() <= '9')) {
88     *size = 1;
89     return true;
90   }
91   return false;
92 }
93
94 // 宣言のコメントを参照してください。
95 bool term::HexValueChecker::operator()(const unicode::UniChar& ch) {
96   return (('a' <= ch.rawcode() && ch.rawcode() <= 'f') ||
97           ('A' <= ch.rawcode() && ch.rawcode() <= 'F') ||
98           ('0' <= ch.rawcode() && ch.rawcode() <= '9'));
99 }
100
101 // 宣言のコメントを参照してください。
102 bool term::IntralineWhitespace::operator()(reader::IReader* reader,
103                                            unsigned int* size) {
104   unicode::UniChar ch(reader->Peek());
105   if (ch.rawcode() == ' ' || ch.rawcode() == '\t') {
106     *size = 1;
107     return true;
108   }
109   return false;
110 }
111
112 // 宣言のコメントを参照してください。
113 bool term::Letter::operator()(reader::IReader* reader,
114                               unsigned int* size) {
115   unicode::UniChar ch(reader->Peek());
116   if (unicode::IsAlphabet(ch)) {
117     *size = 1;
118     return true;
119   }
120   return false;
121 }
122
123 // 宣言のコメントを参照してください。
124 bool term::SpecialInitial::operator()(reader::IReader* reader,
125                               unsigned int* size) {
126   unicode::UniChar ch(reader->Peek());
127   switch (ch.rawcode()) {
128     case kExclamation:
129     case kDoller:
130     case kPercentage:
131     case kAmpersand:
132     case kAsterisk:
133     case kSlash:
134     case kColon:
135     case kLessThan:
136     case kEqual:
137     case kGreaterThan:
138     case kQuestion:
139     case kCap:
140     case kUnderscore:
141     case kTilda:
142       *size = 1;
143       return true;
144     default:
145       return false;
146   }
147 }
148
149 // 宣言のコメントを参照してください。
150 bool term::SpecialSubsequent::operator()(reader::IReader* reader,
151                                          unsigned int* size) {
152   unicode::UniChar ch(reader->Peek());
153   switch (ch.rawcode()) {
154     case kPlus:
155     case kMinus:
156     case kDot:
157     case kAtmark:
158       *size = 1;
159       return true;
160     default:
161       return false;
162   }
163 }
164
165 // 宣言のコメントを参照してください。
166 bool term::Digit::operator()(reader::IReader* reader,
167                              unsigned int* size) {
168   unicode::UniChar ch(reader->Peek());
169   if (unicode::IsNumeric(ch)) {
170     *size = 1;
171     return true;
172   }
173   return false;
174 }
175
176 // 宣言のコメントを参照してください。
177 bool term::PeculiarIdentifier::operator()(reader::IReader* reader,
178                                           unsigned int* size) {
179   unicode::UniChar ch(reader->Peek());
180   if (ch.rawcode() == '+') {
181     *size = 1;
182     return true;
183   } else if (ch.rawcode() == '-') {
184     unicode::UniString tmp(unicode::Convert(reader->Peek(2)));
185     if (tmp == unicode::Convert("->")) {
186       *size = 2;
187     } else {
188       *size = 1;
189     }
190     return true;
191   } else if (ch.rawcode() == '.') {
192     unicode::UniString tmp(unicode::Convert(reader->Peek(3)));
193     if (tmp == unicode::Convert("...")) {
194       *size = 3;
195       return true;
196     }
197   }
198   return false;
199 }
200
201 // 宣言のコメントを参照してください。
202 bool term::ExponentMarker::operator()(reader::IReader* reader,
203                                       unsigned int* size) {
204   unicode::UniChar ch(reader->Peek());
205   switch (ch.rawcode()) {
206     case 'e':
207     case 'E':
208     case 'l':
209     case 'L':
210     case 's':
211     case 'S':
212     case 'f':
213     case 'F':
214     case 'd':
215     case 'D':
216       *size = 1;
217       return true;
218     default:
219       return false;
220   }
221 }
222
223 // 宣言のコメントを参照してください。
224 bool term::Sign::operator()(reader::IReader* reader,
225                             unsigned int* size) {
226   unicode::UniChar ch(reader->Peek());
227   if (ch.rawcode() == '+' || ch.rawcode() == '-') {
228     *size = 1;
229     return true;
230   }
231   *size = 0;
232   return true;
233 }
234
235 // 宣言のコメントを参照してください。
236 bool term::Exactness::operator()(reader::IReader* reader,
237                                  unsigned int* size) {
238   unicode::UniString str(unicode::Convert(reader->Peek(2)));
239   if (str == unicode::Convert("#e") || str == unicode::Convert("#E") ||
240       str == unicode::Convert("#i") || str == unicode::Convert("#I")) {
241     *size = 2;
242     return true;
243   }
244   *size = 0;
245   return true;
246 }
247
248 // 宣言のコメントを参照してください。
249 bool term::Naninf::operator()(reader::IReader* reader,
250                               unsigned int* size) {
251   unicode::UniString code(unicode::Convert(reader->Peek(kNaninfSize)));
252   if (code == unicode::Convert("nan.0") || code == unicode::Convert("inf.0")) {
253     *size = kNaninfSize;
254     return true;
255   }
256   return false;
257 }
258
259 // 宣言のコメントを参照してください。
260 bool term::Boolean::operator()(reader::IReader* reader, unsigned int* size) {
261   unicode::UniString code(unicode::Convert(reader->Peek(kBooleanReadSize)));
262   if (code == unicode::Convert("#f") || code == unicode::Convert("#F") ||
263       code == unicode::Convert("#t") || code == unicode::Convert("#T")) {
264     *size = kBooleanReadSize;
265     return true;
266   }
267   return false;
268 }
269
270 // 宣言のコメントを参照してください。
271 bool term::DatumComment::operator()(reader::IReader* reader,
272                                     unsigned int* size) {
273   unicode::UniString code(unicode::Convert(
274       reader->Peek(kDatumCommentReadSize)));
275   if (code == unicode::Convert("#;")) {
276     *size = kDatumCommentReadSize;
277     return true;
278   }
279   return false;
280 }
281
282 // 宣言のコメントを参照してください。
283 bool term::SpecialComment::operator()(reader::IReader* reader,
284                                     unsigned int* size) {
285   unicode::UniString code(unicode::Convert(
286       reader->Peek(kSpecialCommentReadSize)));
287   if (code == unicode::Convert("#!r6rs")) {
288     *size = kSpecialCommentReadSize;
289     return true;
290   }
291   return false;
292 }