From 92896d22026ad8b95622a9c21d57df8d9f7e3269 Mon Sep 17 00:00:00 2001 From: Justin Ethier Date: Wed, 19 May 2021 18:50:45 -0700 Subject: [PATCH] Issue #459 - R7RS #d decimal specifier --- CHANGELOG.md | 1 + runtime.c | 26 ++++++++++++++++++-------- 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3978b9d3..9972cf29 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ Features - Improve performance of runtime by more efficiently unboxing known fixnums. +- Add support for R7RS `#d` decimal specifier for numbers. Bug Fixes diff --git a/runtime.c b/runtime.c index 38f511ce..17f2d513 100644 --- a/runtime.c +++ b/runtime.c @@ -7553,14 +7553,22 @@ static void _read_return_number(void *data, port_type *p, int base, int exact) // TODO: validation? p->tok_buf[p->tok_end] = '\0'; // TODO: what if buffer is full? p->tok_end = 0; // Reset for next atom - make_empty_vector(vec); - make_string(str, p->tok_buf); - vec.num_elements = 3; - vec.elements = (object *) alloca(sizeof(object) * vec.num_elements); - vec.elements[0] = &str; - vec.elements[1] = obj_int2obj(base); - vec.elements[2] = exact ? boolean_t : boolean_f; - return_thread_runnable_with_obj(data, &vec, p); + if (exact > 1) { + // Special case, we don't know if exact or inexact + make_string(str, p->tok_buf); + str.num_cp = Cyc_utf8_count_code_points((uint8_t *)(p->tok_buf)); + make_c_opaque(opq, &str); + return_thread_runnable_with_obj(data, &opq, p); + } else { + make_empty_vector(vec); + make_string(str, p->tok_buf); + vec.num_elements = 3; + vec.elements = (object *) alloca(sizeof(object) * vec.num_elements); + vec.elements[0] = &str; + vec.elements[1] = obj_int2obj(base); + vec.elements[2] = exact ? boolean_t : boolean_f; + return_thread_runnable_with_obj(data, &vec, p); + } } /** @@ -7962,6 +7970,8 @@ void Cyc_io_read_token(void *data, object cont, object port) return_thread_runnable_with_obj(data, boolean_f, p); } else if (c == '\\') { _read_character(data, p); + } else if (c == 'd') { + _read_number(data, p, 10, 2); } else if (c == 'e') { _read_number(data, p, 10, 1); } else if (c == 'i') {