diff --git a/compile_commands.json b/compile_commands.json index 4a3e0a6..213cc84 100644 --- a/compile_commands.json +++ b/compile_commands.json @@ -16,9 +16,9 @@ "main", "src/main.c" ], - "directory": "/Users/abdelrahman/dev/personal/say-it-in-json", - "file": "/Users/abdelrahman/dev/personal/say-it-in-json/src/main.c", - "output": "/Users/abdelrahman/dev/personal/say-it-in-json/main" + "directory": "/mnt/3A5CDF785CDF2CFF/Users/abdoo/dev/say_it_in_json", + "file": "/mnt/3A5CDF785CDF2CFF/Users/abdoo/dev/say_it_in_json/src/main.c", + "output": "/mnt/3A5CDF785CDF2CFF/Users/abdoo/dev/say_it_in_json/main" }, { "arguments": [ @@ -37,9 +37,9 @@ "main", "src/dstring/dstring.c" ], - "directory": "/Users/abdelrahman/dev/personal/say-it-in-json", - "file": "/Users/abdelrahman/dev/personal/say-it-in-json/src/dstring/dstring.c", - "output": "/Users/abdelrahman/dev/personal/say-it-in-json/main" + "directory": "/mnt/3A5CDF785CDF2CFF/Users/abdoo/dev/say_it_in_json", + "file": "/mnt/3A5CDF785CDF2CFF/Users/abdoo/dev/say_it_in_json/src/dstring/dstring.c", + "output": "/mnt/3A5CDF785CDF2CFF/Users/abdoo/dev/say_it_in_json/main" }, { "arguments": [ @@ -58,9 +58,9 @@ "main", "src/json_entities/json_entities.c" ], - "directory": "/Users/abdelrahman/dev/personal/say-it-in-json", - "file": "/Users/abdelrahman/dev/personal/say-it-in-json/src/json_entities/json_entities.c", - "output": "/Users/abdelrahman/dev/personal/say-it-in-json/main" + "directory": "/mnt/3A5CDF785CDF2CFF/Users/abdoo/dev/say_it_in_json", + "file": "/mnt/3A5CDF785CDF2CFF/Users/abdoo/dev/say_it_in_json/src/json_entities/json_entities.c", + "output": "/mnt/3A5CDF785CDF2CFF/Users/abdoo/dev/say_it_in_json/main" }, { "arguments": [ @@ -79,9 +79,9 @@ "main", "src/lexer/lexer.c" ], - "directory": "/Users/abdelrahman/dev/personal/say-it-in-json", - "file": "/Users/abdelrahman/dev/personal/say-it-in-json/src/lexer/lexer.c", - "output": "/Users/abdelrahman/dev/personal/say-it-in-json/main" + "directory": "/mnt/3A5CDF785CDF2CFF/Users/abdoo/dev/say_it_in_json", + "file": "/mnt/3A5CDF785CDF2CFF/Users/abdoo/dev/say_it_in_json/src/lexer/lexer.c", + "output": "/mnt/3A5CDF785CDF2CFF/Users/abdoo/dev/say_it_in_json/main" }, { "arguments": [ @@ -100,8 +100,373 @@ "main", "src/parser/parser.c" ], - "directory": "/Users/abdelrahman/dev/personal/say-it-in-json", - "file": "/Users/abdelrahman/dev/personal/say-it-in-json/src/parser/parser.c", - "output": "/Users/abdelrahman/dev/personal/say-it-in-json/main" + "directory": "/mnt/3A5CDF785CDF2CFF/Users/abdoo/dev/say_it_in_json", + "file": "/mnt/3A5CDF785CDF2CFF/Users/abdoo/dev/say_it_in_json/src/parser/parser.c", + "output": "/mnt/3A5CDF785CDF2CFF/Users/abdoo/dev/say_it_in_json/main" + }, + { + "arguments": [ + "/usr/bin/clang-16", + "-cc1", + "-triple", + "x86_64-redhat-linux-gnu", + "-emit-obj", + "-mrelax-all", + "-disable-free", + "-clear-ast-before-backend", + "-disable-llvm-verifier", + "-discard-value-names", + "-main-file-name", + "-mrelocation-model", + "static", + "-mframe-pointer=all", + "-fmath-errno", + "-ffp-contract=on", + "-fno-rounding-math", + "-mconstructor-aliases", + "-funwind-tables=2", + "-target-cpu", + "x86-64", + "-tune-cpu", + "generic", + "-mllvm", + "-treat-scalable-fixed-error-as-warning", + "-debug-info-kind=constructor", + "-dwarf-version=4", + "-debugger-tuning=gdb", + "-fcoverage-compilation-dir=/home/abdelrahman/dev_work/say_it_in_json", + "-resource-dir", + "/usr/lib64/clang/16", + "-I", + "include", + "-I", + "include/dstring", + "-I", + "include/json_entities", + "-I", + "include/lexer", + "-I", + "include/parser", + "-internal-isystem", + "/usr/lib64/clang/16/include", + "-internal-isystem", + "/usr/local/include", + "-internal-isystem", + "/usr/bin/../lib/gcc/x86_64-redhat-linux/13/../../../../x86_64-redhat-linux/include", + "-internal-externc-isystem", + "/include", + "-internal-externc-isystem", + "/usr/include", + "-Wall", + "-Werror", + "-pedantic", + "-fdebug-compilation-dir=/home/abdelrahman/dev_work/say_it_in_json", + "-ferror-limit", + "19", + "-fgnuc-version=4.2.1", + "-fcolor-diagnostics", + "-faddrsig", + "-D__GCC_HAVE_DWARF2_CFI_ASM=1", + "-x", + "c", + "-o", + "/tmp/main-9b4cff.o", + "src/main.c" + ], + "directory": "/mnt/3A5CDF785CDF2CFF/Users/abdoo/dev/say_it_in_json", + "file": "/mnt/3A5CDF785CDF2CFF/Users/abdoo/dev/say_it_in_json/src/main.c", + "output": "/tmp/main-9b4cff.o" + }, + { + "arguments": [ + "/usr/bin/clang-16", + "-cc1", + "-triple", + "x86_64-redhat-linux-gnu", + "-emit-obj", + "-mrelax-all", + "-disable-free", + "-clear-ast-before-backend", + "-disable-llvm-verifier", + "-discard-value-names", + "-main-file-name", + "-mrelocation-model", + "static", + "-mframe-pointer=all", + "-fmath-errno", + "-ffp-contract=on", + "-fno-rounding-math", + "-mconstructor-aliases", + "-funwind-tables=2", + "-target-cpu", + "x86-64", + "-tune-cpu", + "generic", + "-mllvm", + "-treat-scalable-fixed-error-as-warning", + "-debug-info-kind=constructor", + "-dwarf-version=4", + "-debugger-tuning=gdb", + "-fcoverage-compilation-dir=/home/abdelrahman/dev_work/say_it_in_json", + "-resource-dir", + "/usr/lib64/clang/16", + "-I", + "include", + "-I", + "include/dstring", + "-I", + "include/json_entities", + "-I", + "include/lexer", + "-I", + "include/parser", + "-internal-isystem", + "/usr/lib64/clang/16/include", + "-internal-isystem", + "/usr/local/include", + "-internal-isystem", + "/usr/bin/../lib/gcc/x86_64-redhat-linux/13/../../../../x86_64-redhat-linux/include", + "-internal-externc-isystem", + "/include", + "-internal-externc-isystem", + "/usr/include", + "-Wall", + "-Werror", + "-pedantic", + "-fdebug-compilation-dir=/home/abdelrahman/dev_work/say_it_in_json", + "-ferror-limit", + "19", + "-fgnuc-version=4.2.1", + "-fcolor-diagnostics", + "-faddrsig", + "-D__GCC_HAVE_DWARF2_CFI_ASM=1", + "-x", + "c", + "-o", + "/tmp/dstring-a07695.o", + "src/dstring/dstring.c" + ], + "directory": "/mnt/3A5CDF785CDF2CFF/Users/abdoo/dev/say_it_in_json", + "file": "/mnt/3A5CDF785CDF2CFF/Users/abdoo/dev/say_it_in_json/src/dstring/dstring.c", + "output": "/tmp/dstring-a07695.o" + }, + { + "arguments": [ + "/usr/bin/clang-16", + "-cc1", + "-triple", + "x86_64-redhat-linux-gnu", + "-emit-obj", + "-mrelax-all", + "-disable-free", + "-clear-ast-before-backend", + "-disable-llvm-verifier", + "-discard-value-names", + "-main-file-name", + "-mrelocation-model", + "static", + "-mframe-pointer=all", + "-fmath-errno", + "-ffp-contract=on", + "-fno-rounding-math", + "-mconstructor-aliases", + "-funwind-tables=2", + "-target-cpu", + "x86-64", + "-tune-cpu", + "generic", + "-mllvm", + "-treat-scalable-fixed-error-as-warning", + "-debug-info-kind=constructor", + "-dwarf-version=4", + "-debugger-tuning=gdb", + "-fcoverage-compilation-dir=/home/abdelrahman/dev_work/say_it_in_json", + "-resource-dir", + "/usr/lib64/clang/16", + "-I", + "include", + "-I", + "include/dstring", + "-I", + "include/json_entities", + "-I", + "include/lexer", + "-I", + "include/parser", + "-internal-isystem", + "/usr/lib64/clang/16/include", + "-internal-isystem", + "/usr/local/include", + "-internal-isystem", + "/usr/bin/../lib/gcc/x86_64-redhat-linux/13/../../../../x86_64-redhat-linux/include", + "-internal-externc-isystem", + "/include", + "-internal-externc-isystem", + "/usr/include", + "-Wall", + "-Werror", + "-pedantic", + "-fdebug-compilation-dir=/home/abdelrahman/dev_work/say_it_in_json", + "-ferror-limit", + "19", + "-fgnuc-version=4.2.1", + "-fcolor-diagnostics", + "-faddrsig", + "-D__GCC_HAVE_DWARF2_CFI_ASM=1", + "-x", + "c", + "-o", + "/tmp/json_entities-bcc119.o", + "src/json_entities/json_entities.c" + ], + "directory": "/mnt/3A5CDF785CDF2CFF/Users/abdoo/dev/say_it_in_json", + "file": "/mnt/3A5CDF785CDF2CFF/Users/abdoo/dev/say_it_in_json/src/json_entities/json_entities.c", + "output": "/tmp/json_entities-bcc119.o" + }, + { + "arguments": [ + "/usr/bin/clang-16", + "-cc1", + "-triple", + "x86_64-redhat-linux-gnu", + "-emit-obj", + "-mrelax-all", + "-disable-free", + "-clear-ast-before-backend", + "-disable-llvm-verifier", + "-discard-value-names", + "-main-file-name", + "-mrelocation-model", + "static", + "-mframe-pointer=all", + "-fmath-errno", + "-ffp-contract=on", + "-fno-rounding-math", + "-mconstructor-aliases", + "-funwind-tables=2", + "-target-cpu", + "x86-64", + "-tune-cpu", + "generic", + "-mllvm", + "-treat-scalable-fixed-error-as-warning", + "-debug-info-kind=constructor", + "-dwarf-version=4", + "-debugger-tuning=gdb", + "-fcoverage-compilation-dir=/home/abdelrahman/dev_work/say_it_in_json", + "-resource-dir", + "/usr/lib64/clang/16", + "-I", + "include", + "-I", + "include/dstring", + "-I", + "include/json_entities", + "-I", + "include/lexer", + "-I", + "include/parser", + "-internal-isystem", + "/usr/lib64/clang/16/include", + "-internal-isystem", + "/usr/local/include", + "-internal-isystem", + "/usr/bin/../lib/gcc/x86_64-redhat-linux/13/../../../../x86_64-redhat-linux/include", + "-internal-externc-isystem", + "/include", + "-internal-externc-isystem", + "/usr/include", + "-Wall", + "-Werror", + "-pedantic", + "-fdebug-compilation-dir=/home/abdelrahman/dev_work/say_it_in_json", + "-ferror-limit", + "19", + "-fgnuc-version=4.2.1", + "-fcolor-diagnostics", + "-faddrsig", + "-D__GCC_HAVE_DWARF2_CFI_ASM=1", + "-x", + "c", + "-o", + "/tmp/lexer-2e4754.o", + "src/lexer/lexer.c" + ], + "directory": "/mnt/3A5CDF785CDF2CFF/Users/abdoo/dev/say_it_in_json", + "file": "/mnt/3A5CDF785CDF2CFF/Users/abdoo/dev/say_it_in_json/src/lexer/lexer.c", + "output": "/tmp/lexer-2e4754.o" + }, + { + "arguments": [ + "/usr/bin/clang-16", + "-cc1", + "-triple", + "x86_64-redhat-linux-gnu", + "-emit-obj", + "-mrelax-all", + "-disable-free", + "-clear-ast-before-backend", + "-disable-llvm-verifier", + "-discard-value-names", + "-main-file-name", + "-mrelocation-model", + "static", + "-mframe-pointer=all", + "-fmath-errno", + "-ffp-contract=on", + "-fno-rounding-math", + "-mconstructor-aliases", + "-funwind-tables=2", + "-target-cpu", + "x86-64", + "-tune-cpu", + "generic", + "-mllvm", + "-treat-scalable-fixed-error-as-warning", + "-debug-info-kind=constructor", + "-dwarf-version=4", + "-debugger-tuning=gdb", + "-fcoverage-compilation-dir=/home/abdelrahman/dev_work/say_it_in_json", + "-resource-dir", + "/usr/lib64/clang/16", + "-I", + "include", + "-I", + "include/dstring", + "-I", + "include/json_entities", + "-I", + "include/lexer", + "-I", + "include/parser", + "-internal-isystem", + "/usr/lib64/clang/16/include", + "-internal-isystem", + "/usr/local/include", + "-internal-isystem", + "/usr/bin/../lib/gcc/x86_64-redhat-linux/13/../../../../x86_64-redhat-linux/include", + "-internal-externc-isystem", + "/include", + "-internal-externc-isystem", + "/usr/include", + "-Wall", + "-Werror", + "-pedantic", + "-fdebug-compilation-dir=/home/abdelrahman/dev_work/say_it_in_json", + "-ferror-limit", + "19", + "-fgnuc-version=4.2.1", + "-fcolor-diagnostics", + "-faddrsig", + "-D__GCC_HAVE_DWARF2_CFI_ASM=1", + "-x", + "c", + "-o", + "/tmp/parser-2d2a43.o", + "src/parser/parser.c" + ], + "directory": "/mnt/3A5CDF785CDF2CFF/Users/abdoo/dev/say_it_in_json", + "file": "/mnt/3A5CDF785CDF2CFF/Users/abdoo/dev/say_it_in_json/src/parser/parser.c", + "output": "/tmp/parser-2d2a43.o" } ] diff --git a/include/parser/parser.h b/include/parser/parser.h index 99cef3d..0a27d01 100644 --- a/include/parser/parser.h +++ b/include/parser/parser.h @@ -1,6 +1,7 @@ #ifndef PARSER_H #define PARSER_H +#include "json_entities.h" #include "lexer.h" void parse_token(token_t token); diff --git a/src/parser/parser.c b/src/parser/parser.c index 9e1cfba..b05e414 100644 --- a/src/parser/parser.c +++ b/src/parser/parser.c @@ -3,129 +3,40 @@ #include "dstring.h" #include "json_entities.h" #include "lexer.h" +#include #include INTERNAL jentity_t *current = NULL; +INTERNAL jcoll_t *get_collection_from_entity(const jentity_t *entity); +INTERNAL jentity_t *create_new_single_entity(const jval_t value, + jentity_t *parent); +INTERNAL jentity_t *create_new_pair_entity(dstr_t *key, const jval_t value, + jentity_t *parent); +INTERNAL void add_key(jentity_t **entity, dstr_t *key, const jval_t *value); +INTERNAL jentity_t *add_value(jentity_t **entity, const jval_t *value); +INTERNAL void add_collection(jentity_t **entity, const jval_t *value); + void parse_token(token_t token) { switch (token.type) { - case TK_L_BRACE: { - jval_t value = (jval_t){ - .type = JVAL_COLLECTION, - .collection = (jcoll_t *)malloc(sizeof(jcoll_t)), - }; - - value.collection->type = JCOLL_OBJECT; - value.collection->size = 0; - value.collection->begin = NULL; - value.collection->end = NULL; - - if (!current) { - current = (jentity_t *)malloc(sizeof(jentity_t)); - current->type = JENTITY_SINGLE; - current->value = value; - current->parent = NULL; - current->next = NULL; - } else { - jcoll_t *collection = NULL; - - if (current->type == JENTITY_SINGLE) { - collection = current->value.collection; - } else { - collection = current->pair.value.collection; - } - - if (!(collection->end)) { - collection->begin = collection->end = - (jentity_t *)malloc(sizeof(jentity_t)); - collection->end->type = JENTITY_SINGLE; - collection->end->value = value; - collection->end->parent = current; - collection->end->next = NULL; - - current = collection->end; - } else { - if (collection->end->type == JENTITY_PAIR && - collection->end->pair.value.type == JVAL_EMPTY) { - collection->end->pair.value = value; - - current = collection->end; - } else { - jentity_t *entity = (jentity_t *)malloc(sizeof(jentity_t)); - - entity->type = JENTITY_SINGLE; - entity->value = value; - entity->parent = current; - entity->next = NULL; - - collection->end->next = entity; - - collection->end = entity; - - current = entity; - } - } - } - - break; - } + case TK_L_BRACE: case TK_L_BRACKET: { jval_t value = (jval_t){ .type = JVAL_COLLECTION, .collection = (jcoll_t *)malloc(sizeof(jcoll_t)), }; - value.collection->type = JCOLL_ARRAY; + if (token.type == TK_L_BRACE) { + value.collection->type = JCOLL_OBJECT; + } else { + value.collection->type = JCOLL_ARRAY; + } + value.collection->size = 0; value.collection->begin = NULL; value.collection->end = NULL; - if (!current) { - current = (jentity_t *)malloc(sizeof(jentity_t)); - current->type = JENTITY_SINGLE; - current->value = value; - current->parent = NULL; - current->next = NULL; - } else { - jcoll_t *collection = NULL; - - if (current->type == JENTITY_SINGLE) { - collection = current->value.collection; - } else { - collection = current->pair.value.collection; - } - - if (!(collection->end)) { - collection->begin = collection->end = - (jentity_t *)malloc(sizeof(jentity_t)); - collection->end->type = JENTITY_SINGLE; - collection->end->value = value; - collection->end->parent = current; - collection->end->next = current; - - current = collection->end; - } else { - if (collection->end->type == JENTITY_PAIR && - collection->end->pair.value.type == JVAL_EMPTY) { - collection->end->pair.value = value; - - current = collection->end; - } else { - jentity_t *entity = (jentity_t *)malloc(sizeof(jentity_t)); - - entity->type = JENTITY_SINGLE; - entity->value = value; - entity->parent = current; - entity->next = NULL; - - collection->end->next = entity; - - collection->end = entity; - - current = entity; - } - } - } + add_collection(¤t, &value); break; } @@ -136,41 +47,17 @@ void parse_token(token_t token) { } break; + case TK_STR_KEY: { + jval_t value = (jval_t){.type = JVAL_EMPTY, .null_val = NULL}; + + add_key(¤t, dstr_from_string(token.value.string), &value); + + break; + } case TK_NULL: { jval_t value = (jval_t){.type = JVAL_NULL, .null_val = NULL}; - jcoll_t *collection = NULL; - - if (current->type == JENTITY_SINGLE) { - collection = current->value.collection; - } else { - collection = current->pair.value.collection; - } - - if (!(collection->end)) { - collection->begin = collection->end = - (jentity_t *)malloc(sizeof(jentity_t)); - collection->end->type = JENTITY_SINGLE; - collection->end->value = value; - collection->end->parent = current; - collection->end->next = NULL; - } else { - if (collection->end->type == JENTITY_PAIR && - collection->end->pair.value.type == JVAL_EMPTY) { - collection->end->pair.value = value; - } else { - jentity_t *entity = (jentity_t *)malloc(sizeof(jentity_t)); - - entity->type = JENTITY_SINGLE; - entity->value = value; - entity->parent = current; - entity->next = NULL; - - collection->end->next = entity; - - collection->end = entity; - } - } + add_value(¤t, &value); break; } @@ -178,73 +65,7 @@ void parse_token(token_t token) { jval_t value = (jval_t){.type = JVAL_BOOLEAN, .boolean = token.value.boolean}; - jcoll_t *collection = NULL; - - if (current->type == JENTITY_SINGLE) { - collection = current->value.collection; - } else { - collection = current->pair.value.collection; - } - - if (!(collection->end)) { - collection->begin = collection->end = - (jentity_t *)malloc(sizeof(jentity_t)); - collection->end->type = JENTITY_SINGLE; - collection->end->value = value; - collection->end->parent = current; - collection->end->next = NULL; - } else { - if (collection->end->type == JENTITY_PAIR && - collection->end->pair.value.type == JVAL_EMPTY) { - collection->end->pair.value = value; - } else { - jentity_t *entity = (jentity_t *)malloc(sizeof(jentity_t)); - - entity->type = JENTITY_SINGLE; - entity->value = value; - entity->parent = current; - entity->next = NULL; - - collection->end->next = entity; - - collection->end = entity; - } - } - - break; - } - case TK_STR_KEY: { - jval_t value = (jval_t){.type = JVAL_EMPTY, .null_val = NULL}; - - jcoll_t *collection = NULL; - - if (current->type == JENTITY_SINGLE) { - collection = current->value.collection; - } else { - collection = current->pair.value.collection; - } - - if (!(collection->end)) { - collection->begin = collection->end = - (jentity_t *)malloc(sizeof(jentity_t)); - collection->end->type = JENTITY_PAIR; - collection->end->pair.key = dstr_from_string(token.value.string); - collection->end->pair.value = value; - collection->end->parent = current; - collection->end->next = NULL; - } else { - jentity_t *entity = (jentity_t *)malloc(sizeof(jentity_t)); - - entity->type = JENTITY_PAIR; - entity->pair.key = dstr_from_string(token.value.string); - entity->pair.value = value; - entity->parent = current; - entity->next = NULL; - - collection->end->next = entity; - - collection->end = entity; - } + add_value(¤t, &value); break; } @@ -252,38 +73,7 @@ void parse_token(token_t token) { jval_t value = (jval_t){.type = JVAL_STRING, .string = dstr_from_string(token.value.string)}; - jcoll_t *collection = NULL; - - if (current->type == JENTITY_SINGLE) { - collection = current->value.collection; - } else { - collection = current->pair.value.collection; - } - - if (!(collection->end)) { - collection->begin = collection->end = - (jentity_t *)malloc(sizeof(jentity_t)); - collection->end->type = JENTITY_SINGLE; - collection->end->value = value; - collection->end->parent = current; - collection->end->next = NULL; - } else { - if (collection->end->type == JENTITY_PAIR && - collection->end->pair.value.type == JVAL_EMPTY) { - collection->end->pair.value = value; - } else { - jentity_t *entity = (jentity_t *)malloc(sizeof(jentity_t)); - - entity->type = JENTITY_SINGLE; - entity->value = value; - entity->parent = current; - entity->next = NULL; - - collection->end->next = entity; - - collection->end = entity; - } - } + add_value(¤t, &value); break; } @@ -291,38 +81,7 @@ void parse_token(token_t token) { jval_t value = (jval_t){.type = JVAL_INTEGER, .num_int = token.value.num_int}; - jcoll_t *collection = NULL; - - if (current->type == JENTITY_SINGLE) { - collection = current->value.collection; - } else { - collection = current->pair.value.collection; - } - - if (!(collection->end)) { - collection->begin = collection->end = - (jentity_t *)malloc(sizeof(jentity_t)); - collection->end->type = JENTITY_SINGLE; - collection->end->value = value; - collection->end->parent = current; - collection->end->next = NULL; - } else { - if (collection->end->type == JENTITY_PAIR && - collection->end->pair.value.type == JVAL_EMPTY) { - collection->end->pair.value = value; - } else { - jentity_t *entity = (jentity_t *)malloc(sizeof(jentity_t)); - - entity->type = JENTITY_SINGLE; - entity->value = value; - entity->parent = current; - entity->next = NULL; - - collection->end->next = entity; - - collection->end = entity; - } - } + add_value(¤t, &value); break; } @@ -330,38 +89,7 @@ void parse_token(token_t token) { jval_t value = (jval_t){.type = JVAL_DOUBLE, .num_dbl = token.value.num_frac}; - jcoll_t *collection = NULL; - - if (current->type == JENTITY_SINGLE) { - collection = current->value.collection; - } else { - collection = current->pair.value.collection; - } - - if (!(collection->end)) { - collection->begin = collection->end = - (jentity_t *)malloc(sizeof(jentity_t)); - collection->end->type = JENTITY_SINGLE; - collection->end->value = value; - collection->end->parent = current; - collection->end->parent = NULL; - } else { - if (collection->end->type == JENTITY_PAIR && - collection->end->pair.value.type == JVAL_EMPTY) { - collection->end->pair.value = value; - } else { - jentity_t *entity = (jentity_t *)malloc(sizeof(jentity_t)); - - entity->type = JENTITY_SINGLE; - entity->value = value; - entity->parent = current; - entity->next = NULL; - - collection->end->next = entity; - - collection->end = entity; - } - } + add_value(¤t, &value); break; } @@ -369,3 +97,103 @@ void parse_token(token_t token) { break; } } + +jcoll_t *get_collection_from_entity(const jentity_t *entity) { + return entity->type == JENTITY_SINGLE ? entity->value.collection + : entity->pair.value.collection; +} + +jentity_t *create_new_single_entity(const jval_t value, jentity_t *parent) { + jentity_t *entity = (jentity_t *)malloc(sizeof(jentity_t)); + + if (!entity) { + return NULL; + } + + entity->type = JENTITY_SINGLE; + entity->value = value; + entity->parent = parent; + entity->next = NULL; + + return entity; +} + +jentity_t *create_new_pair_entity(dstr_t *key, const jval_t value, + jentity_t *parent) { + jentity_t *entity = (jentity_t *)malloc(sizeof(jentity_t)); + + if (!entity) { + return NULL; + } + + entity->type = JENTITY_PAIR; + entity->pair.key = key; + entity->pair.value = value; + entity->parent = parent; + entity->next = NULL; + + return entity; +} + +void add_key(jentity_t **entity, dstr_t *key, const jval_t *value) { + jcoll_t *collection = get_collection_from_entity(*entity); + + if (!collection) { + return; + } + + if (!(collection->end)) { + collection->begin = collection->end = + create_new_pair_entity(key, *value, *entity); + + collection->size = 1; + } else { + jentity_t *new_entity = create_new_pair_entity(key, *value, *entity); + + collection->end->next = new_entity; + + collection->end = new_entity; + + ++(collection->size); + } +} + +jentity_t *add_value(jentity_t **entity, const jval_t *value) { + jcoll_t *collection = get_collection_from_entity(*entity); + + if (!collection) { + return NULL; + } + + if (!(collection->end)) { + collection->begin = collection->end = + create_new_single_entity(*value, *entity); + + collection->size = 1; + } else { + if (collection->end->type == JENTITY_PAIR && + collection->end->pair.value.type == JVAL_EMPTY) { + collection->end->pair.value = *value; + } else { + jentity_t *new_entity = create_new_single_entity(*value, *entity); + + collection->end->next = new_entity; + + collection->end = new_entity; + + ++(collection->size); + } + } + + return collection->end; +} + +void add_collection(jentity_t **entity, const jval_t *value) { + if (!(*entity)) { + *entity = create_new_single_entity(*value, NULL); + + return; + } + + *entity = add_value(entity, value); +}