From b71624abffe8ff975814d7ff5400ec5ddb9c2767 Mon Sep 17 00:00:00 2001 From: Bruce Hill Date: Tue, 13 Feb 2024 23:37:24 -0500 Subject: Fix floating point literals to be exactly precise --- compile.c | 7 ++++++- util.h | 2 ++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/compile.c b/compile.c index d48a296a..4611305e 100644 --- a/compile.c +++ b/compile.c @@ -35,7 +35,12 @@ CORD compile(env_t *env, ast_t *ast) case Bool: return Match(ast, Bool)->b ? "yes" : "no"; case Var: return Match(ast, Var)->name; case Int: return CORD_asprintf("I%ld(%ld)", Match(ast, Int)->precision, Match(ast, Int)->i); - case Num: return CORD_asprintf(Match(ast, Num)->precision == 64 ? "%g" : "%gf", Match(ast, Num)->n); + case Num: { + // HACK: since the cord library doesn't support the '%a' specifier, this workaround + // is necessary: + char *buf = asprintfa(Match(ast, Num)->precision == 64 ? "%a" : "%af", Match(ast, Num)->n); + return CORD_from_char_star(buf); + } case UnaryOp: { auto unop = Match(ast, UnaryOp); CORD expr = compile(env, unop->value); diff --git a/util.h b/util.h index 1c098781..68ce2c9f 100644 --- a/util.h +++ b/util.h @@ -27,6 +27,8 @@ char *heap_strf(const char *fmt, ...); CORD CORD_asprintf(const char *fmt, ...); #define CORD_appendf(cord, fmt, ...) CORD_sprintf(cord, "%r" fmt, *(cord) __VA_OPT__(,) __VA_ARGS__) +#define asprintfa(...) ({ char *_buf = alloca(snprintf(0, 0, __VA_ARGS__)); sprintf(_buf, __VA_ARGS__); _buf; }) + #define REVERSE_LIST(list) do { \ __typeof(list) _prev = NULL; \ __typeof(list) _next = NULL; \ -- cgit v1.2.3