From 803deb4a70180f987fdeb99d617631cf9a092b4d Mon Sep 17 00:00:00 2001 From: Martin Kagamino Lehoux Date: Mon, 10 Feb 2025 22:07:19 +0100 Subject: fix(string): Valid string copy --- json.c | 11 ++++------- main.c | 10 ++++++---- string.c | 2 +- 3 files changed, 11 insertions(+), 12 deletions(-) diff --git a/json.c b/json.c index e68d617..4a49bbf 100644 --- a/json.c +++ b/json.c @@ -72,7 +72,7 @@ typedef struct { } parse_string_result; parse_string_result parse_string(Arena *a, Str src, uintptr_t pos) { - printf("json.parse_string: %s", src.data + pos); + printf("json.parse_string: %s\n", src.data + pos); assert(src.data[pos] == '"'); int i = 1; @@ -81,18 +81,15 @@ parse_string_result parse_string(Arena *a, Str src, uintptr_t pos) { assert(i + pos <= src.len); } assert(src.data[pos + i]); - char *s; - memcpy(s, src.data + pos + 1, i - 1); + Str s = Str_copy(a, &src.data[pos + 1], i - 1); - printf("%s", s); - - return (parse_string_result){Str_copy(a, src.data + pos + 1, i - 1), pos + i}; + return (parse_string_result){s, pos + i}; } JSON JSON_parse(Arena *a, Str src) { JSON json = {0}; int pos = 0; - // printf("json.parse: src=%s", src.data); + printf("json.parse: src=%s\n", src.data); if (isdigit(src.data[pos])) { parse_integer_result result = parse_integer(a, src, 0); json.integer = &result.value; diff --git a/main.c b/main.c index 0910b3d..145d768 100644 --- a/main.c +++ b/main.c @@ -22,7 +22,10 @@ typedef struct { int main() { Arena perm = Arena_new(128e3); + // Testing string assert(Str_equals(S("Bonjour"), S("Bonjour"))); + Str s = S("Hello"); + assert(Str_equals(s, Str_copy(&perm, s.data, s.len))); // Testing JSON printf("Arena: mem=%d B\n", Arena_get_used(perm)); JSON json_int = JSON_parse(&perm, S("123")); @@ -39,9 +42,8 @@ int main() { printf("Arena: mem=%d B\n", Arena_get_used(perm)); assert(*Vec_get(JSON_parse(&perm, S("[1, 2, 3]")).array, int, 1) == 2); printf("Arena: mem=%d B\n", Arena_get_used(perm)); - Str a = S("\"abc\""); - JSON s = JSON_parse(&perm, S("\"abc\"")); - // printf("%s (%d)\n", s.string->data, s.string->len); - // assert(Str_equals(*JSON_parse(&perm, S("\"abc\"")).string, S("abc")) == 1); + JSON js = JSON_parse(&perm, S("\"abc\"")); + assert(Str_equals(*js.string, S("abc")) == 1); + printf("Arena: mem=%d B\n", Arena_get_used(perm)); return 0; } diff --git a/string.c b/string.c index 509163f..ec7af39 100644 --- a/string.c +++ b/string.c @@ -25,7 +25,7 @@ uint64_t Str_hash64(Str s) { } Str Str_copy(Arena *a, char *data, uintptr_t len) { - Str str = {0}; + Str str = {0,len}; str.data = new (a, char, len); if (str.len) memcpy(str.data, data, len); -- cgit v1.3 From 577fe25f20c2e04b5e6444fbbbbcbc0e93943d7d Mon Sep 17 00:00:00 2001 From: Martin Kagamino Lehoux Date: Mon, 10 Feb 2025 22:11:54 +0100 Subject: refactor(json): Input char* --- json.c | 44 +++++++++++++++++++++----------------------- json.h | 2 +- main.c | 8 ++++---- 3 files changed, 26 insertions(+), 28 deletions(-) diff --git a/json.c b/json.c index 4a49bbf..6948edf 100644 --- a/json.c +++ b/json.c @@ -5,7 +5,6 @@ #include #include #include -#include #include "string.h" @@ -14,11 +13,11 @@ typedef struct { uintptr_t pos; } parse_integer_result; -parse_integer_result parse_integer(Arena *a, Str src, uintptr_t pos) { +parse_integer_result parse_integer(Arena *a, char *src, uintptr_t pos) { int *ints = new (a, int, 16); // TODO: reuse in parsing int i = 0; - while (isdigit(src.data[pos + i])) { - int val = (src.data[pos + i] - '0'); + while (isdigit(src[pos + i])) { + int val = (src[pos + i] - '0'); ints[i] = val; i++; } @@ -30,9 +29,9 @@ parse_integer_result parse_integer(Arena *a, Str src, uintptr_t pos) { return (parse_integer_result){result, pos + i}; } -uintptr_t absorb_whitespaces(Str src, uintptr_t pos) { +uintptr_t absorb_whitespaces(char *src, uintptr_t pos) { int i = 0; - while (isspace(src.data[pos + i])) { + while (isspace(src[pos + i])) { i++; } return pos + i; @@ -43,9 +42,9 @@ typedef struct { uintptr_t pos; } parse_array_result; -parse_array_result parse_array(Arena *a, Str src, uintptr_t start_pos) { - printf("json.parse_array: parsing array %s\n", src.data + start_pos); - assert(src.data[start_pos] == '['); +parse_array_result parse_array(Arena *a, char *src, uintptr_t start_pos) { + printf("json.parse_array: parsing array %s\n", src + start_pos); + assert(src[start_pos] == '['); uintptr_t pos = start_pos + 1; Vec *items = Vec_new(a, JSON, 0); for (;;) { @@ -55,13 +54,13 @@ parse_array_result parse_array(Arena *a, Str src, uintptr_t start_pos) { items = Vec_push(a, items, &result.value); pos = result.pos; pos = absorb_whitespaces(src, pos); - if (src.data[pos] == ',') { + if (src[pos] == ',') { pos++; } else { break; } }; - assert(src.data[pos] == ']'); + assert(src[pos] == ']'); return (parse_array_result){items, pos + 1}; } @@ -71,36 +70,35 @@ typedef struct { uintptr_t pos; } parse_string_result; -parse_string_result parse_string(Arena *a, Str src, uintptr_t pos) { - printf("json.parse_string: %s\n", src.data + pos); - assert(src.data[pos] == '"'); +parse_string_result parse_string(Arena *a, char *src, uintptr_t pos) { + printf("json.parse_string: %s\n", src + pos); + assert(src[pos] == '"'); int i = 1; - while (src.data[pos + i] != '"' && src.data[pos + i - 1] != '\\') { + while (src[pos + i] != '"' && src[pos + i - 1] != '\\') { i++; - assert(i + pos <= src.len); } - assert(src.data[pos + i]); - Str s = Str_copy(a, &src.data[pos + 1], i - 1); + assert(src[pos + i]); + Str s = Str_copy(a, &src[pos + 1], i - 1); return (parse_string_result){s, pos + i}; } -JSON JSON_parse(Arena *a, Str src) { +JSON JSON_parse(Arena *a, char *src) { JSON json = {0}; int pos = 0; - printf("json.parse: src=%s\n", src.data); - if (isdigit(src.data[pos])) { + printf("json.parse: src=%s\n", src); + if (isdigit(src[pos])) { parse_integer_result result = parse_integer(a, src, 0); json.integer = &result.value; pos = result.pos; } - if (src.data[pos] == '[') { + if (src[pos] == '[') { parse_array_result result = parse_array(a, src, pos); json.array = result.items; pos = result.pos; } - if (src.data[pos] == '"') { + if (src[pos] == '"') { parse_string_result result = parse_string(a, src, pos); json.string = &result.string; pos = result.pos; diff --git a/json.h b/json.h index 588cb6b..072f97d 100644 --- a/json.h +++ b/json.h @@ -9,5 +9,5 @@ typedef struct { Vec *array; Str *string; } JSON; -JSON JSON_parse(Arena *a, Str src); +JSON JSON_parse(Arena *a, char *src); #endif diff --git a/main.c b/main.c index 145d768..ca21ea8 100644 --- a/main.c +++ b/main.c @@ -28,10 +28,10 @@ int main() { assert(Str_equals(s, Str_copy(&perm, s.data, s.len))); // Testing JSON printf("Arena: mem=%d B\n", Arena_get_used(perm)); - JSON json_int = JSON_parse(&perm, S("123")); + JSON json_int = JSON_parse(&perm, "123"); assert(*json_int.integer == 123); printf("Arena: mem=%d B\n", Arena_get_used(perm)); - JSON json_int_array = JSON_parse(&perm, S("[1,2,3]")); + JSON json_int_array = JSON_parse(&perm, "[1,2,3]"); assert(json_int_array.integer == NULL); assert(json_int_array.array->len == 3); int sum = 0; @@ -40,9 +40,9 @@ int main() { } assert(sum == 6); printf("Arena: mem=%d B\n", Arena_get_used(perm)); - assert(*Vec_get(JSON_parse(&perm, S("[1, 2, 3]")).array, int, 1) == 2); + assert(*Vec_get(JSON_parse(&perm, "[1, 2, 3]").array, int, 1) == 2); printf("Arena: mem=%d B\n", Arena_get_used(perm)); - JSON js = JSON_parse(&perm, S("\"abc\"")); + JSON js = JSON_parse(&perm, "\"abc\""); assert(Str_equals(*js.string, S("abc")) == 1); printf("Arena: mem=%d B\n", Arena_get_used(perm)); return 0; -- cgit v1.3 From b5b3fa6b5e20c49137e26268c64d66eb652c3eb7 Mon Sep 17 00:00:00 2001 From: Martin Kagamino Lehoux Date: Mon, 10 Feb 2025 22:15:14 +0100 Subject: test: Add tests on arena memory usage --- main.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/main.c b/main.c index ca21ea8..8d46d82 100644 --- a/main.c +++ b/main.c @@ -28,9 +28,11 @@ int main() { assert(Str_equals(s, Str_copy(&perm, s.data, s.len))); // Testing JSON printf("Arena: mem=%d B\n", Arena_get_used(perm)); + assert(Arena_get_used(perm) == 5); JSON json_int = JSON_parse(&perm, "123"); assert(*json_int.integer == 123); printf("Arena: mem=%d B\n", Arena_get_used(perm)); + assert(Arena_get_used(perm) == 72); JSON json_int_array = JSON_parse(&perm, "[1,2,3]"); assert(json_int_array.integer == NULL); assert(json_int_array.array->len == 3); @@ -40,10 +42,13 @@ int main() { } assert(sum == 6); printf("Arena: mem=%d B\n", Arena_get_used(perm)); + assert(Arena_get_used(perm) == 304); assert(*Vec_get(JSON_parse(&perm, "[1, 2, 3]").array, int, 1) == 2); printf("Arena: mem=%d B\n", Arena_get_used(perm)); + assert(Arena_get_used(perm) == 536); JSON js = JSON_parse(&perm, "\"abc\""); assert(Str_equals(*js.string, S("abc")) == 1); printf("Arena: mem=%d B\n", Arena_get_used(perm)); + assert(Arena_get_used(perm) == 539); return 0; } -- cgit v1.3 From c0ef18f1aad1c5b4d8cb0aa1e0bab8d54d99e7f6 Mon Sep 17 00:00:00 2001 From: Martin Kagamino Lehoux Date: Tue, 11 Feb 2025 06:09:21 +0100 Subject: chore(vscode): VSCode debugger --- .vscode/launch.json | 16 ++++++++++++++++ .vscode/settings.json | 6 ++++++ 2 files changed, 22 insertions(+) create mode 100644 .vscode/launch.json create mode 100644 .vscode/settings.json diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..3b84b2e --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,16 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "type": "lldb", + "request": "launch", + "name": "Debug", + "program": "${workspaceFolder}/Debug/main", + "args": [], + "cwd": "${workspaceFolder}" + } + ] +} diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..36ecaad --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,6 @@ +{ + "lldb.displayFormat": "auto", + "lldb.showDisassembly": "auto", + "lldb.dereferencePointers": true, + "lldb.consoleMode": "evaluate" +} \ No newline at end of file -- cgit v1.3 From 10379fdde9fa5e94a955fe35f14e5b35de2a0e5d Mon Sep 17 00:00:00 2001 From: Martin Kagamino Lehoux Date: Tue, 11 Feb 2025 06:28:17 +0100 Subject: chore: Makefile --- .gitignore | 6 ++---- CMakeLists.txt | 3 ++- Makefile | 9 +++++++++ README.md | 3 +++ log.c | 2 +- vec.c | 4 ---- 6 files changed, 17 insertions(+), 10 deletions(-) create mode 100644 Makefile create mode 100644 README.md diff --git a/.gitignore b/.gitignore index e7ea508..58c83ee 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,4 @@ main -cmake_install.cmake -Makefile -CMakeFiles/ -CMakeCache.txt +Debug/ +Release/ diff --git a/CMakeLists.txt b/CMakeLists.txt index c94bd65..ddba94b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,6 @@ cmake_minimum_required(VERSION 3.30.5) project(kagamic VERSION 0.1 LANGUAGES C) +set(CMAKE_C_STANDARD 17) add_executable(main main.c string.h string.c @@ -9,4 +10,4 @@ add_executable(main log.h log.c ) target_link_libraries(main m) -target_compile_options(main PRIVATE -Wall) +target_compile_options(main PRIVATE -Wall -pedantic -Wextra) diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..71dea2a --- /dev/null +++ b/Makefile @@ -0,0 +1,9 @@ +debug: + cd Debug; \ + cmake -DCMAKE_BUILD_TYPE=Debug ..; \ + make; + +release: + cd Release; \ + cmake -DCMAKE_BUILD_TYPE=Release ..; \ + make; diff --git a/README.md b/README.md new file mode 100644 index 0000000..431a2d0 --- /dev/null +++ b/README.md @@ -0,0 +1,3 @@ +# Kagamic + +## TODO diff --git a/log.c b/log.c index 9a3211f..76bee11 100644 --- a/log.c +++ b/log.c @@ -8,4 +8,4 @@ void info(Logger l, const char *name, const char *str, ...) { printf(str); printf("\n"); } -}; +} diff --git a/vec.c b/vec.c index 6962d03..58977dc 100644 --- a/vec.c +++ b/vec.c @@ -1,4 +1,3 @@ -#include #include #include "vec.h" @@ -14,9 +13,6 @@ Vec *_Vec_new(Arena *a, int size, ptrdiff_t cap, int align) { } Vec *Vec_push(Arena *a, Vec *v, void *data) { - // printf("push: dest=%p, src=%p, size=%d\n", v->data + v->len * v->size, - // data, - // v->size); if (v->len == v->cap) { void *cpy = alloc(a, v->cap * 2, v->size, v->align); memcpy(cpy, v->data, v->len * v->size); -- cgit v1.3 From 92a97df033086d0ed88c38ad1efe4a2a023eb5fe Mon Sep 17 00:00:00 2001 From: Martin Kagamino Lehoux Date: Tue, 11 Feb 2025 06:33:33 +0100 Subject: feat(json): Reduce int memory usage --- README.md | 2 ++ json.c | 2 +- main.c | 8 ++++---- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 431a2d0..24274e1 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,5 @@ # Kagamic ## TODO + +- Testing setup diff --git a/json.c b/json.c index 6948edf..cf40634 100644 --- a/json.c +++ b/json.c @@ -14,7 +14,7 @@ typedef struct { } parse_integer_result; parse_integer_result parse_integer(Arena *a, char *src, uintptr_t pos) { - int *ints = new (a, int, 16); // TODO: reuse in parsing + char ints[16]; int i = 0; while (isdigit(src[pos + i])) { int val = (src[pos + i] - '0'); diff --git a/main.c b/main.c index 8d46d82..2028049 100644 --- a/main.c +++ b/main.c @@ -32,7 +32,7 @@ int main() { JSON json_int = JSON_parse(&perm, "123"); assert(*json_int.integer == 123); printf("Arena: mem=%d B\n", Arena_get_used(perm)); - assert(Arena_get_used(perm) == 72); + assert(Arena_get_used(perm) == 5); JSON json_int_array = JSON_parse(&perm, "[1,2,3]"); assert(json_int_array.integer == NULL); assert(json_int_array.array->len == 3); @@ -42,13 +42,13 @@ int main() { } assert(sum == 6); printf("Arena: mem=%d B\n", Arena_get_used(perm)); - assert(Arena_get_used(perm) == 304); + assert(Arena_get_used(perm) == 48); assert(*Vec_get(JSON_parse(&perm, "[1, 2, 3]").array, int, 1) == 2); printf("Arena: mem=%d B\n", Arena_get_used(perm)); - assert(Arena_get_used(perm) == 536); + assert(Arena_get_used(perm) == 88); JSON js = JSON_parse(&perm, "\"abc\""); assert(Str_equals(*js.string, S("abc")) == 1); printf("Arena: mem=%d B\n", Arena_get_used(perm)); - assert(Arena_get_used(perm) == 539); + assert(Arena_get_used(perm) == 91); return 0; } -- cgit v1.3 From d3d71bb044e0ae9af75bd74d4030e1d95f18a68e Mon Sep 17 00:00:00 2001 From: Martin Kagamino Lehoux Date: Fri, 14 Feb 2025 08:08:57 +0100 Subject: feat(json): Nested parsing --- Makefile | 2 ++ README.md | 3 +++ json.c | 67 ++++++++++++++++++++++++++++++++++++++------------------------- json.h | 1 + main.c | 37 ++++++++++++++++++++++++++--------- memory.c | 1 - string.c | 2 +- vec.c | 19 +++++++++--------- vec.h | 4 ++-- 9 files changed, 87 insertions(+), 49 deletions(-) diff --git a/Makefile b/Makefile index 71dea2a..58cdf1f 100644 --- a/Makefile +++ b/Makefile @@ -1,9 +1,11 @@ debug: + mkdir -p Debug; \ cd Debug; \ cmake -DCMAKE_BUILD_TYPE=Debug ..; \ make; release: + mkdir -p Release; \ cd Release; \ cmake -DCMAKE_BUILD_TYPE=Release ..; \ make; diff --git a/README.md b/README.md index 24274e1..6536ed4 100644 --- a/README.md +++ b/README.md @@ -3,3 +3,6 @@ ## TODO - Testing setup +- JSON objet as kv +- Vec push no need to reallocate vec, only items. Same for Str? Read about stack pointers in C +- Vec_get not safe, I made a type mistake. And should be more efficient for loops diff --git a/json.c b/json.c index cf40634..197dca3 100644 --- a/json.c +++ b/json.c @@ -9,7 +9,13 @@ #include "string.h" typedef struct { - int value; + JSON *value; + uintptr_t pos; +} parse_any_result; +parse_any_result parse_any(Arena *a, char *src, uintptr_t pos); + +typedef struct { + int *value; uintptr_t pos; } parse_integer_result; @@ -21,11 +27,11 @@ parse_integer_result parse_integer(Arena *a, char *src, uintptr_t pos) { ints[i] = val; i++; } - int result = 0; + int *result = new (a, int, 1); for (int j = 0; j < i; j++) { - result += ints[j] * pow(10, (i - j - 1)); + *result += ints[j] * pow(10, (i - j - 1)); } - printf("json.parse_integer: parsed int=%d at pos=%lu\n", result, pos); + printf("json.parse_integer: parsed int=%d at pos=%lu\n", *result, pos); return (parse_integer_result){result, pos + i}; } @@ -42,16 +48,15 @@ typedef struct { uintptr_t pos; } parse_array_result; -parse_array_result parse_array(Arena *a, char *src, uintptr_t start_pos) { - printf("json.parse_array: parsing array %s\n", src + start_pos); - assert(src[start_pos] == '['); - uintptr_t pos = start_pos + 1; - Vec *items = Vec_new(a, JSON, 0); +parse_array_result parse_array(Arena *a, char *src, uintptr_t pos) { + printf("json.parse_array: parsing array %s\n", src + pos); + assert(src[pos] == '['); + pos++; + Vec items = Vec_new(a, JSON, 2); for (;;) { pos = absorb_whitespaces(src, pos); - parse_integer_result result = parse_integer(a, src, pos); - assert(result.pos > pos); - items = Vec_push(a, items, &result.value); + parse_any_result result = parse_any(a, src, pos); + Vec_push(a, &items, result.value); pos = result.pos; pos = absorb_whitespaces(src, pos); if (src[pos] == ',') { @@ -62,7 +67,7 @@ parse_array_result parse_array(Arena *a, char *src, uintptr_t start_pos) { }; assert(src[pos] == ']'); - return (parse_array_result){items, pos + 1}; + return (parse_array_result){&items, pos + 1}; } typedef struct { @@ -78,31 +83,39 @@ parse_string_result parse_string(Arena *a, char *src, uintptr_t pos) { while (src[pos + i] != '"' && src[pos + i - 1] != '\\') { i++; } - assert(src[pos + i]); + assert(src[pos + i] == '"'); Str s = Str_copy(a, &src[pos + 1], i - 1); - return (parse_string_result){s, pos + i}; + return (parse_string_result){s, pos + i + 1}; } -JSON JSON_parse(Arena *a, char *src) { - JSON json = {0}; - int pos = 0; - printf("json.parse: src=%s\n", src); +parse_any_result parse_any(Arena *a, char *src, uintptr_t pos) { + JSON *value = new (a, JSON, 1); if (isdigit(src[pos])) { - parse_integer_result result = parse_integer(a, src, 0); - json.integer = &result.value; + parse_integer_result result = parse_integer(a, src, pos); + value->integer = result.value; pos = result.pos; - } - if (src[pos] == '[') { + } else if (src[pos] == '[') { parse_array_result result = parse_array(a, src, pos); - json.array = result.items; + value->array = result.items; pos = result.pos; - } - if (src[pos] == '"') { + } else if (src[pos] == '"') { parse_string_result result = parse_string(a, src, pos); - json.string = &result.string; + value->string = &result.string; pos = result.pos; } + return (parse_any_result){value, pos}; +} + +JSON JSON_parse(Arena *a, char *src) { + parse_any_result result = parse_any(a, src, 0); + return *result.value; +} + +JSON JSON_Int(Arena *a, int val) { + JSON json = {0}; + json.integer = new (a, int, 1); + *json.integer = val; return json; } diff --git a/json.h b/json.h index 072f97d..44b064e 100644 --- a/json.h +++ b/json.h @@ -10,4 +10,5 @@ typedef struct { Str *string; } JSON; JSON JSON_parse(Arena *a, char *src); +JSON JSON_Int(Arena *a, int val); #endif diff --git a/main.c b/main.c index 2028049..88d7855 100644 --- a/main.c +++ b/main.c @@ -21,34 +21,53 @@ typedef struct { } User; int main() { - Arena perm = Arena_new(128e3); // Testing string + Arena perm = Arena_new(128e3); assert(Str_equals(S("Bonjour"), S("Bonjour"))); Str s = S("Hello"); assert(Str_equals(s, Str_copy(&perm, s.data, s.len))); - // Testing JSON printf("Arena: mem=%d B\n", Arena_get_used(perm)); assert(Arena_get_used(perm) == 5); + // Testing JSON + perm = Arena_new(128e3); JSON json_int = JSON_parse(&perm, "123"); assert(*json_int.integer == 123); printf("Arena: mem=%d B\n", Arena_get_used(perm)); - assert(Arena_get_used(perm) == 5); + assert(Arena_get_used(perm) == 28); + // JSON Int Array + perm = Arena_new(128e3); JSON json_int_array = JSON_parse(&perm, "[1,2,3]"); assert(json_int_array.integer == NULL); assert(json_int_array.array->len == 3); + int ints[3]; int sum = 0; for (int i = 0; i < json_int_array.array->len; i++) { - sum += *Vec_get(json_int_array.array, int, i); + JSON *item = Vec_get(json_int_array.array, JSON, i); + ints[i] = *item->integer; + sum += *item->integer; } + printf("sum=%d\n", sum); + assert(ints[0] == 1); + assert(ints[1] == 2); + assert(ints[2] == 3); assert(sum == 6); printf("Arena: mem=%d B\n", Arena_get_used(perm)); - assert(Arena_get_used(perm) == 48); - assert(*Vec_get(JSON_parse(&perm, "[1, 2, 3]").array, int, 1) == 2); - printf("Arena: mem=%d B\n", Arena_get_used(perm)); - assert(Arena_get_used(perm) == 88); + assert(Arena_get_used(perm) == 264); + // JSON String + perm = Arena_new(128e3); JSON js = JSON_parse(&perm, "\"abc\""); assert(Str_equals(*js.string, S("abc")) == 1); printf("Arena: mem=%d B\n", Arena_get_used(perm)); - assert(Arena_get_used(perm) == 91); + assert(Arena_get_used(perm) == 27); + // JSON Nested hybrid array + perm = Arena_new(128e3); + JSON jaa = JSON_parse(&perm, "[[1,\"abc\"]]"); + JSON sub_array = *Vec_get(jaa.array, JSON, 0); + JSON *val_1 = Vec_get(sub_array.array, JSON, 0); + assert(*val_1->integer == 1); + JSON *val_2 = Vec_get(sub_array.array, JSON, 1); + assert(Str_equals(*val_2->string, S("abc"))); + printf("Arena: mem=%d B\n", Arena_get_used(perm)); + assert(Arena_get_used(perm) == 203); return 0; } diff --git a/memory.c b/memory.c index cfb5dd4..f2248b6 100644 --- a/memory.c +++ b/memory.c @@ -1,6 +1,5 @@ #include #include -#include #include #include diff --git a/string.c b/string.c index ec7af39..b07ba02 100644 --- a/string.c +++ b/string.c @@ -25,7 +25,7 @@ uint64_t Str_hash64(Str s) { } Str Str_copy(Arena *a, char *data, uintptr_t len) { - Str str = {0,len}; + Str str = {0, len}; str.data = new (a, char, len); if (str.len) memcpy(str.data, data, len); diff --git a/vec.c b/vec.c index 58977dc..8923f19 100644 --- a/vec.c +++ b/vec.c @@ -1,18 +1,20 @@ #include +#include "assert.h" #include "vec.h" -Vec *_Vec_new(Arena *a, int size, ptrdiff_t cap, int align) { - Vec *v = new (a, Vec, 1); - v->data = alloc(a, cap, size, align); - v->size = size; - v->align = align; - v->cap = cap; - v->len = 0; +Vec _Vec_new(Arena *a, int size, ptrdiff_t cap, int align) { + assert(cap > 0); + Vec v = {0}; + v.data = alloc(a, cap, size, align); + v.size = size; + v.align = align; + v.cap = cap; + v.len = 0; return v; } -Vec *Vec_push(Arena *a, Vec *v, void *data) { +void Vec_push(Arena *a, Vec *v, void *data) { if (v->len == v->cap) { void *cpy = alloc(a, v->cap * 2, v->size, v->align); memcpy(cpy, v->data, v->len * v->size); @@ -20,7 +22,6 @@ Vec *Vec_push(Arena *a, Vec *v, void *data) { } memcpy(v->data + v->len * v->size, data, v->size); v->len++; - return v; } void *_Vec_get(Vec *v, int pos) { diff --git a/vec.h b/vec.h index 9fb9590..f7e5295 100644 --- a/vec.h +++ b/vec.h @@ -13,8 +13,8 @@ typedef struct { int align; } Vec; #define Vec_new(a, T, cap) _Vec_new(a, sizeof(T), cap, _Alignof(T)) -Vec *_Vec_new(Arena *a, int size, ptrdiff_t cap, int align); -Vec *Vec_push(Arena *a, Vec *v, void *data); +Vec _Vec_new(Arena *a, int size, ptrdiff_t cap, int align); +void Vec_push(Arena *a, Vec *v, void *data); #define Vec_get(v, T, p) (T *)_Vec_get(v, p) void *_Vec_get(Vec *v, int pos); #endif -- cgit v1.3