diff options
author | Jo-Philipp Wich <jo@mein.io> | 2021-12-13 12:58:18 +0100 |
---|---|---|
committer | Jo-Philipp Wich <jo@mein.io> | 2022-01-04 15:53:36 +0100 |
commit | b605dbfcf04f310e08634b52507da7a4155bfce1 (patch) | |
tree | 04397dab9be96a5978e08366299671a8aa507267 /include | |
parent | 8907ce41a36f8d42097d884550fb3cfbba62e6c5 (diff) |
treewide: rework numeric value handling
- Parse integer literals as unsigned numeric values in order to be able
to represent the entire unsigned 64bit value range
- Stop parsing minus-prefixed integer literals as negative numbers but
treat them as separate minus operator followed by a positive integer
instead
- Only store unsigned numeric constants in bytecode
- Rework numeric comparison logic to be able to handle full 64bit
unsigned integers
- If possible, yield unsigned 64 bit results for additions
- Simplify numeric value conversion API
- Compile code with -fwrapv for defined signed overflow semantics
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
Diffstat (limited to 'include')
-rw-r--r-- | include/ucode/types.h | 32 | ||||
-rw-r--r-- | include/ucode/vallist.h | 2 |
2 files changed, 29 insertions, 5 deletions
diff --git a/include/ucode/types.h b/include/ucode/types.h index 49d910b..cbd03dd 100644 --- a/include/ucode/types.h +++ b/include/ucode/types.h @@ -372,24 +372,46 @@ void ucv_to_stringbuf_formatted(uc_vm_t *, uc_stringbuf_t *, uc_value_t *, size_ uc_type_t ucv_cast_number(uc_value_t *, int64_t *, double *); +uc_value_t *ucv_to_number(uc_value_t *); + static inline double ucv_to_double(uc_value_t *v) { - int64_t n; + uc_value_t *nv; double d; - return (ucv_cast_number(v, &n, &d) == UC_DOUBLE) ? d : (double)n; + nv = ucv_to_number(v); + d = ucv_double_get(nv); + ucv_put(nv); + + return d; } static inline int64_t ucv_to_integer(uc_value_t *v) { + uc_value_t *nv; int64_t n; - double d; - return (ucv_cast_number(v, &n, &d) == UC_DOUBLE) ? (int64_t)d : n; + nv = ucv_to_number(v); + n = ucv_int64_get(nv); + ucv_put(nv); + + return n; } +static inline uint64_t +ucv_to_unsigned(uc_value_t *v) +{ + uc_value_t *nv; + uint64_t u; + + nv = ucv_to_number(v); + u = ucv_uint64_get(nv); + ucv_put(nv); + + return u; +} static inline bool ucv_is_callable(uc_value_t *uv) @@ -437,7 +459,7 @@ ucv_is_scalar(uc_value_t *uv) bool ucv_is_equal(uc_value_t *, uc_value_t *); bool ucv_is_truish(uc_value_t *); -bool ucv_compare(int, uc_value_t *, uc_value_t *); +bool ucv_compare(int, uc_value_t *, uc_value_t *, int *); uc_value_t *ucv_key_get(uc_vm_t *, uc_value_t *, uc_value_t *); uc_value_t *ucv_key_set(uc_vm_t *, uc_value_t *, uc_value_t *, uc_value_t *); diff --git a/include/ucode/vallist.h b/include/ucode/vallist.h index a3d94e8..47ddc7d 100644 --- a/include/ucode/vallist.h +++ b/include/ucode/vallist.h @@ -41,6 +41,8 @@ typedef enum { TAG_PTR = 6 } uc_value_type_t; +uc_value_t *uc_number_parse(const char *buf, char **end); + void uc_vallist_init(uc_value_list_t *list); void uc_vallist_free(uc_value_list_t *list); |