diff options
author | Bad Diode <bd@badd10de.dev> | 2024-06-15 15:37:34 +0200 |
---|---|---|
committer | Bad Diode <bd@badd10de.dev> | 2024-06-15 15:37:34 +0200 |
commit | 99b92b160af5b9475262676aef7dd7f209429298 (patch) | |
tree | b3c76c52b8351405b356e31601847655834b3af0 | |
parent | 4de23d7e60ba018d6f9bf656f6f3fca4be2473be (diff) | |
download | bdl-99b92b160af5b9475262676aef7dd7f209429298.tar.gz bdl-99b92b160af5b9475262676aef7dd7f209429298.zip |
Add better numeric lexing
-rw-r--r-- | src/main.c | 78 |
1 files changed, 61 insertions, 17 deletions
@@ -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(¤t, | 347 | return emit_token_err(¤t, |
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(¤t, cstr("malformed number")); | ||
367 | } | ||
368 | c = scan_peek(scanner); | ||
369 | if (!(c >= '0' && c <= '9')) { | ||
370 | return emit_token_err(¤t, | ||
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(¤t, 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 | ¤t, | ||
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(¤t, cstr("malformed number")); | ||
368 | } | 412 | } |
369 | } | 413 | } |
370 | return emit_token(current, scanner, TOK_NUMBER); | 414 | return emit_token_err(¤t, cstr("malformed number")); |
371 | } | 415 | } |
372 | 416 | ||
373 | Token | 417 | Token |