Mercurial > projects > dang
comparison lexer/Lexer.d @ 89:a49bb982a7b0 new_gen
Using the new SourceLocation system to handle errors. Also, this is the first push for making the errors don't throw, but continue to check the source.
author | Anders Johnsen <skabet@gmail.com> |
---|---|
date | Sun, 04 May 2008 20:27:01 +0200 |
parents | eb5b2c719a39 |
children | 1a24e61eb104 |
comparison
equal
deleted
inserted
replaced
88:eb5b2c719a39 | 89:a49bb982a7b0 |
---|---|
1 module lexer.Lexer; | 1 module lexer.Lexer; |
2 | 2 |
3 import misc.Error, | 3 import basic.Message, |
4 basic.SourceManager; | 4 basic.SourceManager; |
5 | 5 |
6 import lexer.Token, | 6 import lexer.Token, |
7 lexer.Keyword; | 7 lexer.Keyword; |
8 | 8 |
19 public: | 19 public: |
20 | 20 |
21 /** | 21 /** |
22 Create a new Lexer. | 22 Create a new Lexer. |
23 */ | 23 */ |
24 this(SourceLocation start, SourceManager src_mgr) | 24 |
25 { | 25 |
26 this(SourceLocation start, SourceManager src_mgr, MessageHandler messages) | |
27 { | |
28 this.messages = messages; | |
26 sm = src_mgr; | 29 sm = src_mgr; |
27 start_loc = start; | 30 start_loc = start; |
28 position = 0; | 31 position = 0; |
29 source = sm.getRawData(start_loc); | 32 source = sm.getRawData(start_loc); |
30 | 33 |
110 Token t = this.next; | 113 Token t = this.next; |
111 this.position = oldPosition; | 114 this.position = oldPosition; |
112 return t; | 115 return t; |
113 } | 116 } |
114 | 117 |
115 /** | |
116 Return all errors that occurred while tokenizing the string. | |
117 | |
118 TODO: Error system not implemented yet - this is a stub! | |
119 */ | |
120 public Error[] getErrors() | |
121 { | |
122 return this.errors; | |
123 } | |
124 | |
125 private: | 118 private: |
126 Token eq() | 119 Token eq() |
127 { | 120 { |
128 if(source[position] == '=') | 121 if(source[position] == '=') |
129 return Token(Tok.Eq, Loc(position++ - 1), 2); | 122 return Token(Tok.Eq, Loc(position++ - 1), 2); |
229 ++position; | 222 ++position; |
230 if(source[position-2] == '*') | 223 if(source[position-2] == '*') |
231 if(source[position-1] == '/') | 224 if(source[position-1] == '/') |
232 return this.next; | 225 return this.next; |
233 } | 226 } |
234 throw error(__LINE__, "Unexpected end of file. Unclosed comment block"); | 227 messages.report(UnexpectedEOFBlock,Loc(position)); |
235 | 228 |
236 case '+': | 229 case '+': |
237 position += 2; | 230 position += 2; |
238 int nesting = 1; | 231 int nesting = 1; |
239 while(getNextChar != CharType.EOF) | 232 while(getNextChar != CharType.EOF) |
254 } | 247 } |
255 | 248 |
256 if(nesting == 0) | 249 if(nesting == 0) |
257 return this.next; | 250 return this.next; |
258 } | 251 } |
259 throw error(__LINE__, "Unexpected end of file. Unclosed comment block"); | 252 messages.report(UnexpectedEOFBlock,Loc(position)); |
260 | 253 |
261 default: | 254 default: |
262 return Token(Tok.Slash, Loc(position - 1), 1); | 255 return Token(Tok.Slash, Loc(position - 1), 1); |
263 } | 256 } |
264 } | 257 } |
285 break; | 278 break; |
286 case CharType.Symbol: | 279 case CharType.Symbol: |
287 if(this.source[position+i] == '.') | 280 if(this.source[position+i] == '.') |
288 { | 281 { |
289 if(dot) | 282 if(dot) |
290 throw error(__LINE__,"Only one '.' is allowed in an floating number") | 283 messages.report(OnlyOneDotFloating, Loc(position + i)); |
291 .tok(Token(Tok.Float, Loc(position + i), 1)); | |
292 dot = true; | 284 dot = true; |
293 break; | 285 break; |
294 } | 286 } |
295 end = true; | 287 end = true; |
296 continue; | 288 continue; |
299 break; | 291 break; |
300 if (this.source[position+i] == 'e' || | 292 if (this.source[position+i] == 'e' || |
301 this.source[position+i] == 'E') | 293 this.source[position+i] == 'E') |
302 { | 294 { |
303 if (e) | 295 if (e) |
304 throw error(__LINE__,"Only one '"~this.source[position+i] | 296 messages.report(OnlyOneEFloating, Loc(position + i)); |
305 ~"' is allowed in an floating number"); | |
306 e = true; | 297 e = true; |
307 break; | 298 break; |
308 } | 299 } |
309 end = true; | 300 end = true; |
310 continue; | 301 continue; |
363 char current = source[position + offset]; | 354 char current = source[position + offset]; |
364 | 355 |
365 CharType c = charTable[current]; | 356 CharType c = charTable[current]; |
366 | 357 |
367 if(c == CharType.INVALID) | 358 if(c == CharType.INVALID) |
368 throw error(__LINE__, "Read invalid symbol: '%0'").arg(current); | 359 messages.report(InvalidSymbol, SLoc()).arg(current); |
369 | 360 |
370 return c; | 361 return c; |
371 | 362 |
372 } | |
373 | |
374 Error error(uint line, char[] msg) | |
375 { | |
376 return (new Error(msg));//.loc(Loc(position)); | |
377 } | 363 } |
378 | 364 |
379 private final SourceLocation Loc(int pos = -1) | 365 private final SourceLocation Loc(int pos = -1) |
380 { | 366 { |
381 if (pos < 0) | 367 if (pos < 0) |
385 | 371 |
386 SourceManager sm; | 372 SourceManager sm; |
387 SourceLocation start_loc; | 373 SourceLocation start_loc; |
388 int position; | 374 int position; |
389 char[] source; | 375 char[] source; |
390 Error[] errors; | 376 MessageHandler messages; |
391 CharType[] charTable; | 377 CharType[] charTable; |
392 Token delegate()[] symbolFunctions; | 378 Token delegate()[] symbolFunctions; |
393 } | 379 } |
394 | 380 |
395 enum CharType : ubyte | 381 enum CharType : ubyte |