diff options
| author | Bruce Hill <bruce@bruce-hill.com> | 2026-01-11 19:00:20 -0500 |
|---|---|---|
| committer | Bruce Hill <bruce@bruce-hill.com> | 2026-01-11 19:00:20 -0500 |
| commit | 479788ab3a9297fc68fc6f753241291ba37a7539 (patch) | |
| tree | e572cddcfff202f4daf3db462d7d8e05de733edd /src/compile/expressions.c | |
| parent | cd0a0923a826754b76743ab4e5014c8cffc02839 (diff) | |
Optimize initialization logic for Reals so they avoid parsing at runtime
when possible.
Diffstat (limited to 'src/compile/expressions.c')
| -rw-r--r-- | src/compile/expressions.c | 26 |
1 files changed, 19 insertions, 7 deletions
diff --git a/src/compile/expressions.c b/src/compile/expressions.c index 8230b225..e2c1d68a 100644 --- a/src/compile/expressions.c +++ b/src/compile/expressions.c @@ -1,9 +1,9 @@ // This file defines logic for compiling expressions - #include "expressions.h" #include "../ast.h" #include "../config.h" #include "../environment.h" +#include "../stdlib/reals.h" #include "../stdlib/text.h" #include "../stdlib/util.h" #include "../typecheck.h" @@ -108,12 +108,24 @@ Text_t compile(env_t *env, ast_t *ast) { } case Int: return compile_int(ast); case Num: { - Text_t original = Text$from_str(String(string_slice(ast->start, (size_t)(ast->end - ast->start)))); - original = Text$replace(original, Text("_"), EMPTY_TEXT); - original = Text$replace(original, Text("("), EMPTY_TEXT); - original = Text$replace(original, Text(")"), EMPTY_TEXT); - original = Text$replace(original, Text(" "), EMPTY_TEXT); - return Texts("Real$parse(Text(\"", original, "\"), NULL)"); + const char *src = String(string_slice(ast->start, (size_t)(ast->end - ast->start))); + Text_t corrected = Text$from_str(src); + corrected = Text$replace(corrected, Text("_"), EMPTY_TEXT); + corrected = Text$replace(corrected, Text("("), EMPTY_TEXT); + corrected = Text$replace(corrected, Text(")"), EMPTY_TEXT); + corrected = Text$replace(corrected, Text(" "), EMPTY_TEXT); + + Real_t real = Real$parse(corrected, NULL); + if (!Real$is_boxed(real)) { + return Texts("Real$from_float64(", corrected, ")"); + } + + int64_t num, den; + if (Real$get_rational(real, &num, &den)) { + return Texts("Real$from_rational(", num, "LL, ", den, "LL)"); + } + + return Texts("Real$parse(Text(\"", corrected, "\"), NULL)"); } case Not: { ast_t *value = Match(ast, Not)->value; |
