diff options
| -rw-r--r-- | src/binary.c | 13 | ||||
| -rw-r--r-- | src/binary.h | 28 | ||||
| -rw-r--r-- | src/smrt_arena.h | 3 | ||||
| -rw-r--r-- | src/string.c | 39 | ||||
| -rw-r--r-- | src/string.h | 21 | ||||
| -rw-r--r-- | src/unity.c | 1 |
6 files changed, 99 insertions, 6 deletions
diff --git a/src/binary.c b/src/binary.c new file mode 100644 index 0000000..bf5ac89 --- /dev/null +++ b/src/binary.c @@ -0,0 +1,13 @@ +#include "binary.h" + +strng_t *strng_u64_bin(smrt_arena_t *arena, u64 n) { + strng_t *s = strng_new(arena, 64); + s->len = 64; + for (u8 i = 0; i < 64; i++) { + b8 set = (n & (1ull << i)) != 0; + ((u8*)s)[STRNG_BASE_POS + (63 - i)] = set ? '1' : '0'; + } + + return s; +} + diff --git a/src/binary.h b/src/binary.h new file mode 100644 index 0000000..139d2bf --- /dev/null +++ b/src/binary.h @@ -0,0 +1,28 @@ +#pragma once + +#include "common.h" +#include "log.h" +#include "string.h" + +// Binary representation of u64 +strng_t *strng_u64_bin(smrt_arena_t *arena, u64 n); + +static inline strng_view_t uint_to_binsv_impl(smrt_arena_t *arena, u64 n, u8 bits) { + strng_t *b = strng_u64_bin(arena, n); + strng_view_t svb = sv_from(b); + sv_set_len_right(&svb, bits); + return svb; +} + +// Converts n (u8-u64) to a strng_view_t representing the 0s and 1s +#define UINT_TO_BINSV(arena, n) uint_to_binsv_impl(arena, n, \ + _Generic(n, u8: 8, u16: 16, u32: 32, default: 64)) + +#define LOG_UINT_BINREP(label, n) \ + do { \ + smrta_temp_t _macro_t = QUICK_SCRATCH; \ + auto _macro_n = (n); \ + strng_view_t _macro_svb = UINT_TO_BINSV(_macro_t.arena, _macro_n); \ + log_debug(label": 0b%.*s", SV_FMT(_macro_svb)); \ + QUICK_SCRATCH_E(_macro_t); \ + } while (0) diff --git a/src/smrt_arena.h b/src/smrt_arena.h index 1b6725f..fe40509 100644 --- a/src/smrt_arena.h +++ b/src/smrt_arena.h @@ -26,6 +26,9 @@ smrt_arena_t * smrt_arena_create(u64 reserve_size, u64 commit_size, b32 auto_ #define SMRTA_ALLOC_ARRAY(arena, T, n) (T*)smrt_arena_push(arena, sizeof(T) * (n), true) +#define QUICK_SCRATCH smrta_scratch_start(NULL, 0) +#define QUICK_SCRATCH_E(scratch) smrta_scratch_end(scratch) + typedef struct { smrt_arena_t *arena; u64 start_pos; diff --git a/src/string.c b/src/string.c index 63c886a..0925a43 100644 --- a/src/string.c +++ b/src/string.c @@ -5,6 +5,7 @@ #include <immintrin.h> #include <ctype.h> +#include <stdlib.h> #include <string.h> strng_t *strng_new(smrt_arena_t *arena, u64 size) { @@ -79,6 +80,13 @@ i32 strng_set(strng_t *string, char const *c) { return 0; } +i32 strng_set_ic(strng_t *string, u64 i, char c) { + if (i >= string->alloc_size) return -1; + if (i >= string->len) string->len = i+1; + memset(STRNG_TO(string)+i, c, 1); + return 0; +} + i32 strng_app(strng_t *dest, strng_t const *source) { u64 slen = source->len; u64 nlen = dest->len + slen; @@ -123,6 +131,13 @@ void strng_clear(strng_t *string) { string->len = 0; } +char *strng_malloc_str(strng_t const *string) { + char *s = malloc(string->len); + if (!s) return NULL; + memcpy(s, STRNG_TO(string), string->len); + return s; +} + strng_view_t sv_from_chars(char const* c) { u64 l = strlen(c); return (strng_view_t){ .start=0, @@ -214,6 +229,20 @@ void sv_set_len_right(strng_view_t *sv, u64 n) { sv->start = sv->end - n + 1; } +char sv_get_start(strng_view_t const *sv) { + if (sv_len(sv)) { + return *(sv->string + sv->start); + } + return 0; +} + +char sv_get_end(strng_view_t const *sv){ + if (sv_len(sv)) { + return *(sv->string + sv->end); + } + return 0; +} + i32 sv_find_substr(strng_view_t const *sv, char const *_needle) { u64 nlen = strlen(_needle); u64 hlen = sv_len(sv); @@ -279,6 +308,16 @@ lt_32: return -1; } +u64 sv_count_c(strng_view_t const *sv, char n) { + // TODO: simd + u64 x = 0; + for (u64 i = 0; i < sv_len(sv); i++) { + char c = *((u8*)(SV_TO(*sv))+i); + if (c == n) x++; + } + return x; +} + b32 sv_starts_with(strng_view_t const *sv, char const *prefix) { u64 plen = strlen(prefix); u64 hlen = sv_len(sv); diff --git a/src/string.h b/src/string.h index ea4fd9b..13a433a 100644 --- a/src/string.h +++ b/src/string.h @@ -17,11 +17,12 @@ typedef struct { char const *string; } strng_view_t; -strng_t * strng_new(smrt_arena_t *arena, u64 size); -strng_t *strng_from(smrt_arena_t *arena, char const *c); -strng_t * strng_dup(smrt_arena_t *arena, strng_t const *src); - char * strng_str(smrt_arena_t *arena, strng_t const *string); - i32 strng_set(strng_t *string, char const *c); +strng_t * strng_new(smrt_arena_t *arena, u64 size); +strng_t *strng_from(smrt_arena_t *arena, char const *c); +strng_t * strng_dup(smrt_arena_t *arena, strng_t const *src); + char * strng_str(smrt_arena_t *arena, strng_t const *string); + i32 strng_set(strng_t *string, char const *c); + i32 strng_set_ic(strng_t *string, u64 i, char c); // Append to strng, returns -1 if no space, new len otherwise i32 strng_app(strng_t *dest, strng_t const *source); // Append char* to strng, returns -1 if no space, new len otherwise @@ -30,6 +31,8 @@ strng_t * strng_dup(smrt_arena_t *arena, strng_t const *src); i32 strng_app_v(strng_t *dest, strng_view_t const *source); void strng_clear(strng_t *string); +char *strng_malloc_str(strng_t const *string); + #define STRNG_TO(s) (char *)((u8*)(s)+STRNG_BASE_POS) #define STRNG_FMT(s) (i32)s->len, (char *)((u8*)(s)+STRNG_BASE_POS) @@ -69,7 +72,7 @@ static inline strng_view_t sv_subv(strng_view_t const *src, .max = src->max }; } -static inline strng_view_t sv_drop_left(strng_view_t const *src, u64 n) { +static inline strng_view_t sv_drop_left(strng_view_t const *src, u64 n) { u64 src_len = sv_len(src); u64 m = MIN(src_len, n); return sv_subv(src, m, src_len - m); @@ -107,6 +110,9 @@ static inline void sv_pop_right(strng_view_t *sv) { if (sv->end >= sv->start) static inline void sv_popn_left (strng_view_t *sv, u64 n) { for (u64 i = 0; i < n; i++) sv_pop_left(sv); } static inline void sv_popn_right(strng_view_t *sv, u64 n) { for (u64 i = 0; i < n; i++) sv_pop_right(sv); } +char sv_get_start(strng_view_t const *sv); +char sv_get_end(strng_view_t const *sv); + static inline void sv_reset(strng_view_t *sv) { sv->start=0; sv->end = sv->max; @@ -119,6 +125,9 @@ i32 sv_find_substr(strng_view_t const *sv, char const *needle); // Returns -1 if not found, otherwise distance from sv->start i32 sv_find_char(strng_view_t const *sv, char n); +// Count occurrences of n in sv. +u64 sv_count_c(strng_view_t const *sv, char n); + b32 sv_starts_with(strng_view_t const *sv, char const *prefix); b32 sv_ends_with(strng_view_t const *sv, char const *suffix); static inline b32 sv_starts_with_c(strng_view_t const *sv, char c) { return diff --git a/src/unity.c b/src/unity.c index a694f13..3247458 100644 --- a/src/unity.c +++ b/src/unity.c @@ -17,6 +17,7 @@ // Data structures #include "string.c" +#include "binary.c" #include "vec2.c" #include "slidingwindow.c" #include "vec2sw.c" |