diff options
| author | Bruce Hill <bruce@bruce-hill.com> | 2026-01-11 23:03:00 -0500 |
|---|---|---|
| committer | Bruce Hill <bruce@bruce-hill.com> | 2026-01-11 23:03:00 -0500 |
| commit | 6894dc69374efcc23619e93b040a4224588054cd (patch) | |
| tree | 045adf796e3291349b02d695b24e390929c8446e /src/parse/numbers.c | |
| parent | b97ea6b6ac3498b21321e1f93ccc1a2dd145e9d7 (diff) | |
Refactor some AST logic to keep Ints/Reals as "Integer" and "Number" AST
nodes and use improved parsing logic from Int/Real
Diffstat (limited to 'src/parse/numbers.c')
| -rw-r--r-- | src/parse/numbers.c | 24 |
1 files changed, 18 insertions, 6 deletions
diff --git a/src/parse/numbers.c b/src/parse/numbers.c index 1ab774b4..1c9c6aa1 100644 --- a/src/parse/numbers.c +++ b/src/parse/numbers.c @@ -10,8 +10,14 @@ #include <uniname.h> #include "../ast.h" +#include "../stdlib/datatypes.h" +#include "../stdlib/integers.h" +#include "../stdlib/optionals.h" +#include "../stdlib/reals.h" +#include "../stdlib/text.h" #include "context.h" #include "errors.h" +#include "numbers.h" #include "utils.h" static const double RADIANS_PER_DEGREE = 0.0174532925199432957692369076848861271344287188854172545609719144; @@ -39,14 +45,16 @@ ast_t *parse_int(parse_ctx_t *ctx, const char *pos) { return NULL; if (match(&pos, "%")) { - double n = strtod(str, NULL) / 100.; - return NewAST(ctx->file, start, pos, Number, .n = n); + return parse_num(ctx, start); } else if (match(&pos, "deg")) { - double n = strtod(str, NULL) * RADIANS_PER_DEGREE; - return NewAST(ctx->file, start, pos, Number, .n = n); + return parse_num(ctx, start); } - return NewAST(ctx->file, start, pos, Integer, .str = str); + Text_t text = Text$from_strn(start, (size_t)(pos - start)); + Text_t remainder; + OptionalInt_t i = Int$parse(text, NONE_INT, &remainder); + assert(i.small != 0); + return NewAST(ctx->file, start, pos, Integer, .i = i); } ast_t *parse_num(parse_ctx_t *ctx, const char *pos) { @@ -77,5 +85,9 @@ ast_t *parse_num(parse_ctx_t *ctx, const char *pos) { if (match(&pos, "%")) d /= 100.; else if (match(&pos, "deg")) d *= RADIANS_PER_DEGREE; - return NewAST(ctx->file, start, pos, Number, .n = d); + Text_t text = Text$from_strn(start, (size_t)(pos - start)); + Text_t remainder; + OptionalReal_t real = Real$parse(text, &remainder); + if (Real$is_none(&real, &Real$info)) return NULL; + return NewAST(ctx->file, start, pos, Number, .n = real); } |
