diff options
Diffstat (limited to 'src/parse')
| -rw-r--r-- | src/parse/functions.c | 4 | ||||
| -rw-r--r-- | src/parse/numbers.c | 24 |
2 files changed, 20 insertions, 8 deletions
diff --git a/src/parse/functions.c b/src/parse/functions.c index e4eb1317..6dfa2509 100644 --- a/src/parse/functions.c +++ b/src/parse/functions.c @@ -119,7 +119,7 @@ ast_t *parse_func_def(parse_ctx_t *ctx, const char *pos) { if (match_word(&pos, "inline")) { is_inline = true; } else if (match_word(&pos, "cached")) { - if (!cache_ast) cache_ast = NewAST(ctx->file, pos, pos, Integer, .str = "-1"); + if (!cache_ast) cache_ast = NewAST(ctx->file, pos, pos, Integer, .i = I(-1)); } else if (match_word(&pos, "cache_size")) { whitespace(ctx, &pos); if (!match(&pos, "=")) parser_err(ctx, flag_start, pos, "I expected a value for 'cache_size'"); @@ -153,7 +153,7 @@ ast_t *parse_convert_def(parse_ctx_t *ctx, const char *pos) { if (match_word(&pos, "inline")) { is_inline = true; } else if (match_word(&pos, "cached")) { - if (!cache_ast) cache_ast = NewAST(ctx->file, pos, pos, Integer, .str = "-1"); + if (!cache_ast) cache_ast = NewAST(ctx->file, pos, pos, Integer, .i = I(-1)); } else if (match_word(&pos, "cache_size")) { whitespace(ctx, &pos); if (!match(&pos, "=")) parser_err(ctx, flag_start, pos, "I expected a value for 'cache_size'"); 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); } |
