Print changes
This commit is contained in:
+157
-1
@@ -2,6 +2,7 @@
|
||||
#define INCLUDED_MEMORY_H
|
||||
|
||||
#include <float.h>
|
||||
#include <math.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
@@ -10,7 +11,7 @@
|
||||
|
||||
// Geneal macros
|
||||
#ifndef __has_attribute
|
||||
# define __has_attribute(attr) 0
|
||||
# define __has_attribute(x) 0
|
||||
#endif
|
||||
|
||||
#if __has_attribute(always_inline) && defined(_NDEBUG)
|
||||
@@ -98,6 +99,142 @@ static ALWAYS_INLINE lisp_float64_t INT_TO_FLOAT64_BITS(uint64_t i) {
|
||||
uint32_t: INT_TO_FLOAT32_BITS(i), \
|
||||
uint64_t: INT_TO_FLOAT64_BITS(i))
|
||||
|
||||
#define FLOAT_POSITIVE 0
|
||||
#define FLOAT_NEGATIVE 1
|
||||
typedef struct
|
||||
#if __has_attribute(packed)
|
||||
__attribute__((packed))
|
||||
#endif
|
||||
{
|
||||
uint32_t sign : 1;
|
||||
int32_t exp : 8;
|
||||
uint32_t mantissa : 23;
|
||||
} lisp_float32_parts;
|
||||
#define FLOAT32_MIN_EXP -127
|
||||
#define FLOAT32_MAX_EXP 127
|
||||
#define FLOAT32_MAX_PRECISION 6
|
||||
#define FLOAT32_MAX_MANTISSA 0x7fffff
|
||||
|
||||
typedef struct
|
||||
#if __has_attribute(packed)
|
||||
__attribute__((packed))
|
||||
#endif
|
||||
{
|
||||
uint64_t sign : 1;
|
||||
int64_t exp : 11;
|
||||
uint64_t mantissa : 52;
|
||||
} lisp_float64_parts;
|
||||
#define FLOAT64_MIN_EXP -1023
|
||||
#define FLOAT64_MAX_EXP 1023
|
||||
#define FLOAT64_MAX_PRECISION 15
|
||||
#define FLOAT64_MAX_MANTISSA 0xfffffffffffff
|
||||
|
||||
static ALWAYS_INLINE lisp_float32_parts FLOAT32_TO_PARTS(lisp_float32_t flt) {
|
||||
#if __has_attribute(packed)
|
||||
union {
|
||||
lisp_float32_parts parts;
|
||||
lisp_float32_t flt_val;
|
||||
} conv = {.flt_val = flt};
|
||||
conv.parts.exp -= 127;
|
||||
return conv.parts;
|
||||
#else
|
||||
uint32_t bits = FLOAT_TO_INT_BITS(flt);
|
||||
return (lisp_float32_parts) {
|
||||
.sign = bits >> 31,
|
||||
.exp = (bits >> 23) - 127,
|
||||
.mantissa = bits & 0x7fffff,
|
||||
};
|
||||
#endif
|
||||
}
|
||||
|
||||
static ALWAYS_INLINE lisp_float64_parts FLOAT64_TO_PARTS(lisp_float64_t flt) {
|
||||
#if __has_attribute(packed)
|
||||
union {
|
||||
lisp_float64_parts parts;
|
||||
lisp_float64_t flt_val;
|
||||
} conv = {.flt_val = flt};
|
||||
conv.parts.exp -= 1023;
|
||||
return conv.parts;
|
||||
#else
|
||||
uint64_t bits = FLOAT_TO_INT_BITS(flt);
|
||||
return (lisp_float64_parts) {
|
||||
.sign = bits >> 63,
|
||||
.exp = (bits >> 52) - 1023,
|
||||
.mantissa = bits & 0xfffffffffffff,
|
||||
};
|
||||
#endif
|
||||
}
|
||||
|
||||
#define FLOAT_TO_PARTS(flt) \
|
||||
_Generic((flt), \
|
||||
lisp_float32_t: FLOAT32_TO_PARTS(flt), \
|
||||
lisp_float64_t: FLOAT64_TO_PARTS(flt))
|
||||
|
||||
static ALWAYS_INLINE lisp_float64_t PARTS_TO_FLOAT64(lisp_float64_parts parts) {
|
||||
#if __has_attribute(packed)
|
||||
parts.exp += 1023;
|
||||
union {
|
||||
lisp_float64_parts parts;
|
||||
lisp_float64_t flt_val;
|
||||
} conv = {.parts = parts};
|
||||
return conv.flt_val;
|
||||
#else
|
||||
return INT_TO_FLOAT64_BITS(parts.sign << 63 | (parts.exp + 1023) << 52
|
||||
| parts.mantissa);
|
||||
#endif
|
||||
}
|
||||
|
||||
static ALWAYS_INLINE lisp_float32_t PARTS_TO_FLOAT32(lisp_float32_parts parts) {
|
||||
#if __has_attribute(packed)
|
||||
parts.exp += 127;
|
||||
union {
|
||||
lisp_float32_parts parts;
|
||||
lisp_float32_t flt_val;
|
||||
} conv = {.parts = parts};
|
||||
return conv.flt_val;
|
||||
#else
|
||||
return INT_TO_FLOAT32_BITS(parts.sign << 31 | (parts.exp + 127) << 23
|
||||
| parts.mantissa);
|
||||
#endif
|
||||
}
|
||||
|
||||
#define PARTS_TO_FLOAT(parts) \
|
||||
_Generic((parts), \
|
||||
lisp_float32_parts: PARTS_TO_FLOAT32(parts), \
|
||||
lisp_float64_parts: PARTS_TO_FLOAT64(parts))
|
||||
|
||||
static ALWAYS_INLINE lisp_float32_t LISP_FLOAT32_NAN(void) {
|
||||
return PARTS_TO_FLOAT32((lisp_float32_parts) {
|
||||
.sign = FLOAT_POSITIVE,
|
||||
.exp = FLOAT32_MAX_EXP,
|
||||
.mantissa = FLOAT32_MAX_MANTISSA,
|
||||
});
|
||||
}
|
||||
|
||||
static ALWAYS_INLINE lisp_float32_t LISP_FLOAT32_INF(bool negative) {
|
||||
return PARTS_TO_FLOAT32((lisp_float32_parts) {
|
||||
.sign = negative ? FLOAT_NEGATIVE : FLOAT_POSITIVE,
|
||||
.exp = FLOAT32_MAX_EXP,
|
||||
.mantissa = 0,
|
||||
});
|
||||
}
|
||||
|
||||
static ALWAYS_INLINE lisp_float64_t LISP_FLOAT64_NAN(void) {
|
||||
return PARTS_TO_FLOAT64((lisp_float64_parts) {
|
||||
.sign = FLOAT_POSITIVE,
|
||||
.exp = FLOAT64_MAX_EXP,
|
||||
.mantissa = FLOAT64_MAX_MANTISSA,
|
||||
});
|
||||
}
|
||||
|
||||
static ALWAYS_INLINE lisp_float64_t LISP_FLOAT64_INF(bool negative) {
|
||||
return PARTS_TO_FLOAT64((lisp_float64_parts) {
|
||||
.sign = negative ? FLOAT_NEGATIVE : FLOAT_POSITIVE,
|
||||
.exp = FLOAT64_MAX_EXP,
|
||||
.mantissa = 0,
|
||||
});
|
||||
}
|
||||
|
||||
// Allocator
|
||||
void *lisp_realloc(void *oldptr, size_t size);
|
||||
void *lisp_malloc(size_t size);
|
||||
@@ -130,6 +267,25 @@ static ALWAYS_INLINE void add_timespecs(const struct timespec *t1,
|
||||
out->tv_nsec = nsec;
|
||||
}
|
||||
|
||||
static ALWAYS_INLINE size_t signed_number_length(intmax_t n) {
|
||||
if (!n) {
|
||||
return 1;
|
||||
}
|
||||
size_t sign_part = 0;
|
||||
if (n < 0) {
|
||||
n = -n;
|
||||
sign_part = 1;
|
||||
}
|
||||
return sign_part + floor(log10(n)) + 1;
|
||||
}
|
||||
|
||||
static ALWAYS_INLINE size_t unsigned_number_length(uintmax_t n) {
|
||||
if (!n) {
|
||||
return 1;
|
||||
}
|
||||
return floor(log10(n)) + 1;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
// this is actually size + 1 bytes for the null byte
|
||||
char *buffer;
|
||||
|
||||
Reference in New Issue
Block a user