aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorBad Diode <bd@badd10de.dev>2024-06-15 15:37:34 +0200
committerBad Diode <bd@badd10de.dev>2024-06-15 15:37:34 +0200
commit99b92b160af5b9475262676aef7dd7f209429298 (patch)
treeb3c76c52b8351405b356e31601847655834b3af0 /src
parent4de23d7e60ba018d6f9bf656f6f3fca4be2473be (diff)
downloadbdl-99b92b160af5b9475262676aef7dd7f209429298.tar.gz
bdl-99b92b160af5b9475262676aef7dd7f209429298.zip
Add better numeric lexing
Diffstat (limited to 'src')
-rw-r--r--src/main.c78
1 files changed, 61 insertions, 17 deletions
diff --git a/src/main.c b/src/main.c
index 61d02a7..9246092 100644
--- a/src/main.c
+++ b/src/main.c
@@ -239,8 +239,8 @@ scan_skip_whitespace(Scanner *scanner) {
239 case '\v': { 239 case '\v': {
240 scan_next(scanner); 240 scan_next(scanner);
241 } break; 241 } break;
242 // Found a comment! (skip)
243 case ';': { 242 case ';': {
243 // Found a comment! (skip)
244 scan_skip_line(scanner); 244 scan_skip_line(scanner);
245 } break; 245 } break;
246 default: { 246 default: {
@@ -318,13 +318,13 @@ emit_token_number(Scanner *scanner) {
318 scan_next(scanner); 318 scan_next(scanner);
319 scan_next(scanner); 319 scan_next(scanner);
320 while (scan_has_next(scanner)) { 320 while (scan_has_next(scanner)) {
321 char c = scan_peek(scanner); 321 c = scan_peek(scanner);
322 if (c == '0' || c == '1') { 322 if (c == '0' || c == '1') {
323 scan_next(scanner); 323 scan_next(scanner);
324 continue; 324 continue;
325 } 325 }
326 if (is_valid_split(c)) { 326 if (is_valid_split(c)) {
327 break; 327 return emit_token(current, scanner, TOK_NUMBER);
328 } 328 }
329 scan_skip_until_valid(scanner); 329 scan_skip_until_valid(scanner);
330 return emit_token_err( 330 return emit_token_err(
@@ -334,40 +334,84 @@ emit_token_number(Scanner *scanner) {
334 scan_next(scanner); 334 scan_next(scanner);
335 scan_next(scanner); 335 scan_next(scanner);
336 while (scan_has_next(scanner)) { 336 while (scan_has_next(scanner)) {
337 char c = scan_peek(scanner); 337 c = scan_peek(scanner);
338 if ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || 338 if ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') ||
339 (c >= 'A' && c <= 'F')) { 339 (c >= 'A' && c <= 'F')) {
340 scan_next(scanner); 340 scan_next(scanner);
341 continue; 341 continue;
342 } 342 }
343 if (is_valid_split(c)) { 343 if (is_valid_split(c)) {
344 break; 344 return emit_token(current, scanner, TOK_NUMBER);
345 } 345 }
346 scan_skip_until_valid(scanner); 346 scan_skip_until_valid(scanner);
347 return emit_token_err(&current, 347 return emit_token_err(&current,
348 cstr("malformed number: invalid hex number")); 348 cstr("malformed number: invalid hex number"));
349 } 349 }
350 } else { 350 } else {
351 // TODO: handle fractions, signs and exponents properly. 351 // Integral.
352 while (scan_has_next(scanner)) { 352 while (scan_has_next(scanner)) {
353 char c = scan_peek(scanner); 353 c = scan_peek(scanner);
354 switch (c) { 354 if (c == '.') {
355 case '+': 355 scan_next(scanner);
356 case '-': 356 break;
357 case 'e':
358 case 'E':
359 case '.':
360 scan_next(scanner);
361 continue;
362 } 357 }
363 if (c >= '0' && c <= '9') { 358 if (c >= '0' && c <= '9') {
364 scan_next(scanner); 359 scan_next(scanner);
365 continue; 360 continue;
366 } 361 }
367 break; 362 if (is_valid_split(c)) {
363 return emit_token(current, scanner, TOK_NUMBER);
364 }
365 scan_skip_until_valid(scanner);
366 return emit_token_err(&current, cstr("malformed number"));
367 }
368 c = scan_peek(scanner);
369 if (!(c >= '0' && c <= '9')) {
370 return emit_token_err(&current,
371 cstr("malformed number: no decimal digits"));
372 }
373 // Decimals.
374 while (scan_has_next(scanner)) {
375 c = scan_peek(scanner);
376 if (c == 'e' || c == 'E') {
377 scan_next(scanner);
378 break;
379 }
380 if (c >= '0' && c <= '9') {
381 scan_next(scanner);
382 continue;
383 }
384 if (is_valid_split(c)) {
385 return emit_token(current, scanner, TOK_NUMBER);
386 }
387 scan_skip_until_valid(scanner);
388 return emit_token_err(&current, cstr("malformed number"));
389 }
390 // Exponent.
391 c = scan_peek(scanner);
392 if (c == '+' || c == '-') {
393 scan_next(scanner);
394 }
395 while (scan_has_next(scanner)) {
396 c = scan_peek(scanner);
397 if (c >= '0' && c <= '9') {
398 scan_next(scanner);
399 continue;
400 }
401 if (c == '.') {
402 scan_next(scanner);
403 return emit_token_err(
404 &current,
405 cstr("malformed number: decimals not allowed on exponent"));
406 }
407 if (is_valid_split(c)) {
408 return emit_token(current, scanner, TOK_NUMBER);
409 }
410 scan_skip_until_valid(scanner);
411 return emit_token_err(&current, cstr("malformed number"));
368 } 412 }
369 } 413 }
370 return emit_token(current, scanner, TOK_NUMBER); 414 return emit_token_err(&current, cstr("malformed number"));
371} 415}
372 416
373Token 417Token