Just wrote basic json support. Had not tested yet. In fact, I haven't even finished debugging marie_triangulation algorithm. I am truly running out of time
This commit is contained in:
parent
2c4252847d
commit
78fd9f0816
@ -59,6 +59,8 @@ target_link_libraries(r2c -lm)
|
||||
#add_executable(l2t0 src/l2/tests/data_structures/t0.c)
|
||||
#add_executable(l2t1 src/l2/tests/data_structures/t1.c)
|
||||
|
||||
add_executable(l2_t_parsing src/l2/tests/t_parsing.c)
|
||||
|
||||
add_executable(l2_tex_gen src/l2/anne/codegen.c)
|
||||
target_link_libraries(l2_tex_gen -lm -lpng)
|
||||
|
||||
|
||||
@ -9,13 +9,13 @@ void generate_liza_l1_headers() {
|
||||
mkdir_nofail("l1/eve/liza");
|
||||
// todo: continue OptionT + util_templates_instantiation_options refactoring from here
|
||||
generate_util_templ_inst_eve_header(l, ns, (util_templates_instantiation_options){
|
||||
.T = cstr("BoxLizaSound"), .vec = true});
|
||||
.T = cstr("BoxLizaSound"), .vec = true}, false);
|
||||
generate_util_templ_inst_eve_header(l, ns, (util_templates_instantiation_options){
|
||||
.T = cstr("PlayingSound"), .vec_extended = true});
|
||||
.T = cstr("PlayingSound"), .vec_extended = true}, false);
|
||||
generate_util_templ_inst_eve_header(l, ns, (util_templates_instantiation_options){
|
||||
.T = cstr("BoxLizaInstrument"), .vec = true});
|
||||
.T = cstr("BoxLizaInstrument"), .vec = true}, false);
|
||||
generate_util_templ_inst_eve_header(l, ns, (util_templates_instantiation_options){
|
||||
.T = cstr("MyInstrument"), .vec = true});
|
||||
.T = cstr("MyInstrument"), .vec = true}, false);
|
||||
}
|
||||
|
||||
#endif
|
||||
@ -17,7 +17,7 @@ void generate_l1_lucy_headers(){
|
||||
|
||||
generate_util_templ_inst_eve_header(l, ns, (util_templates_instantiation_options){
|
||||
.T = cstr("LucyPositionedStagingGlyph"), .vec = true, .sort = true,
|
||||
});
|
||||
}, false);
|
||||
}
|
||||
|
||||
#endif
|
||||
@ -11,7 +11,7 @@ void generate_margaret_eve_for_vulkan_utils() {
|
||||
mkdir_nofail("l1/eve/margaret");
|
||||
generate_util_templ_inst_eve_header(l, ns, (util_templates_instantiation_options){
|
||||
.T = cstr("MargaretScoredPhysicalDevice"), .t_primitive = true, .vec = true, .sort = true
|
||||
});
|
||||
}, false);
|
||||
|
||||
/* For l2/margaret/{ vulkan_img_claire.h , vulkan_buffer_claire.h } */
|
||||
generate_eve_span_company_for_primitive(l, ns, cstr("MargaretIAFreeSegment"), true, false);
|
||||
|
||||
@ -12,7 +12,6 @@ void generate_l1_headers_for_marie() {
|
||||
generate_eve_span_company_for_primitive(l, ns, cstr("MarieTriangleAttr"), true, false);
|
||||
/* shape_geom */
|
||||
generate_eve_span_company_for_primitive(l, ns, cstr("MarieEarCuttingTriangulVertState"), true, false);
|
||||
generate_eve_span_company_for_primitive(l, ns, cstr("MarieHoleConnectTriangStackFrame"), true, false);
|
||||
generate_eve_span_company_for_primitive(l, ns, cstr("MarieHoleAndVertexId"), true, false);
|
||||
generate_eve_span_company_for_non_primitive_clonable(l, ns, cstr("VecMarieHoleAndVertexId"), true, false);
|
||||
generate_eve_span_company_for_non_primitive_clonable(l, ns, cstr("VecVecMarieHoleAndVertexId"), true, false);
|
||||
|
||||
@ -17,7 +17,7 @@ void generate_headers_for_r0_r1_r2_r3() {
|
||||
SpanU8 ns = cstr("r2");
|
||||
generate_util_templ_inst_eve_header(l, ns, (util_templates_instantiation_options){
|
||||
.T = cstr("PlayingSound"), .vec_extended = true
|
||||
});
|
||||
}, false);
|
||||
}
|
||||
mkdir_nofail("l1/eve/ds_test");
|
||||
{ /* This structure is needed for testing purposes only */
|
||||
|
||||
@ -67,6 +67,13 @@ void generate_util_temp_very_base_headers() {
|
||||
cstr("#include \"../../gen/l1/pixel_masses.h\"\n"), true, false);
|
||||
|
||||
generate_guarded_span_company_for_primitive(l, ns, cstr("KVPU64ToU64"), cstr(""), true, false);
|
||||
|
||||
/* Currently not clonable, because I forgot to implement clone for rbtree. todo: do this */
|
||||
generate_util_templ_inst_eve_header(l, ns, (util_templates_instantiation_options){
|
||||
.T = cstr("Json"), .t_clonable = false, .vec = true, .skip_declaration_gen = true}, true);
|
||||
|
||||
generate_Option_templ_inst_eve_header(l, ns,
|
||||
(option_template_instantiation_op){.T = cstr("Json"), .t_clonable = false});
|
||||
}
|
||||
|
||||
#endif
|
||||
@ -4,21 +4,30 @@
|
||||
#include "codegen.h"
|
||||
|
||||
// todo: add macro that iterates over vector
|
||||
// todo: add _less_ method
|
||||
// todo: rewrite this crap
|
||||
|
||||
/* if !primitive, requires methods T_drop, and, if also clonable, requires method T_clone */
|
||||
NODISCARD VecU8 generate_VecT_struct_and_base_methods(SpanU8 T, bool primitive, bool clonable) {
|
||||
VecU8 g_VecT = VecU8_fmt("Vec%s", T);
|
||||
SpanU8 VecT = VecU8_to_span(&g_VecT);
|
||||
VecU8 res = VecU8_fmt(
|
||||
"typedef struct {\n"
|
||||
NODISCARD VecU8 generate_VecT_struct(SpanU8 T, bool skip_declaration_gen){
|
||||
VecU8 res = VecU8_new();
|
||||
if (!skip_declaration_gen) {
|
||||
VecU8_append_vec(&res, VecU8_fmt("typedef struct Vec%s Vec%s;\n\n", T, T));
|
||||
}
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"struct Vec%s {\n"
|
||||
SPACE "%s* buf;\n"
|
||||
SPACE "size_t len;\n"
|
||||
SPACE "size_t capacity;\n"
|
||||
"} %s;\n\n", T, VecT);
|
||||
"};\n\n", T, T));
|
||||
return res;
|
||||
}
|
||||
|
||||
VecU8_append_vec(&res, VecU8_fmt("#define %s_new() ((%s){ 0 })\n\n", VecT, VecT));
|
||||
/* if !primitive, requires methods T_drop, and, if also clonable, requires method T_clone */
|
||||
NODISCARD VecU8 generate_VecT_base_methods(SpanU8 T, bool primitive, bool clonable) {
|
||||
VecU8 res = VecU8_new();
|
||||
|
||||
VecU8_append_vec(&res, VecU8_fmt("void %s_drop(%s self) {\n", VecT, VecT));
|
||||
VecU8_append_vec(&res, VecU8_fmt("#define Vec%s_new() ((Vec%s){ 0 })\n\n", T, T));
|
||||
|
||||
VecU8_append_vec(&res, VecU8_fmt("void Vec%s_drop(Vec%s self) {\n", T, T));
|
||||
if (!primitive) {
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
SPACE "for (size_t i = 0; i < self.len; i++) \n"
|
||||
@ -29,12 +38,12 @@ NODISCARD VecU8 generate_VecT_struct_and_base_methods(SpanU8 T, bool primitive,
|
||||
"}\n\n"));
|
||||
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"NODISCARD %s %s_new_reserved(size_t n) {\n"
|
||||
SPACE "return (%s){ .buf = (%s*)safe_calloc(n, sizeof(%s)), .len = 0, .capacity = n };\n"
|
||||
"}\n\n", VecT, VecT, VecT, T, T));
|
||||
"NODISCARD Vec%s Vec%s_new_reserved(size_t n) {\n"
|
||||
SPACE "return (Vec%s){ .buf = (%s*)safe_calloc(n, sizeof(%s)), .len = 0, .capacity = n };\n"
|
||||
"}\n\n", T, T, T, T, T));
|
||||
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"void %s_append(%s* self, %s el) {\n" /* VecT, VecT, T */
|
||||
"void Vec%s_append(Vec%s* self, %s el) {\n" /* T, T, T */
|
||||
SPACE "size_t new_length = self->len + 1;\n"
|
||||
SPACE "if (new_length > self->capacity) {\n"
|
||||
SPACE SPACE "size_t new_capacity = Vec_get_new_capacity(self->capacity, new_length);\n"
|
||||
@ -43,26 +52,26 @@ NODISCARD VecU8 generate_VecT_struct_and_base_methods(SpanU8 T, bool primitive,
|
||||
SPACE "}\n"
|
||||
SPACE "self->buf[self->len] = el;\n"
|
||||
SPACE "self->len = new_length;\n"
|
||||
"}\n\n", VecT, VecT, T, T, T));
|
||||
"}\n\n", T, T, T, T, T));
|
||||
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"%s* %s_mat(%s* self, size_t i) {\n"
|
||||
"%s* Vec%s_mat(Vec%s* self, size_t i) {\n"
|
||||
SPACE "assert(i < self->len);\n"
|
||||
SPACE "return &self->buf[i];\n"
|
||||
"}\n\n", T, VecT, VecT));
|
||||
"}\n\n", T, T, T));
|
||||
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"const %s* %s_at(const %s* self, size_t i) {\n"
|
||||
"const %s* Vec%s_at(const Vec%s* self, size_t i) {\n"
|
||||
SPACE "assert(i < self->len);\n"
|
||||
SPACE "return &self->buf[i];\n"
|
||||
"}\n\n", T, VecT, VecT));
|
||||
"}\n\n", T, T, T));
|
||||
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"void %s_sink(%s* self, size_t new_len) {\n" /* VecT, VecT */
|
||||
"void Vec%s_sink(Vec%s* self, size_t new_len) {\n" /* T, T */
|
||||
SPACE "assert(new_len <= self->len);\n"
|
||||
"%v" /* dropping */
|
||||
SPACE "self->len = new_len;\n"
|
||||
"}\n\n", VecT, VecT,
|
||||
"}\n\n", T, T,
|
||||
primitive ? vcstr("") : VecU8_fmt(
|
||||
SPACE "for (size_t i = new_len; i < self->len; i++)\n"
|
||||
SPACE SPACE "%s_drop(self->buf[i]);\n", /* T */
|
||||
@ -70,9 +79,10 @@ NODISCARD VecU8 generate_VecT_struct_and_base_methods(SpanU8 T, bool primitive,
|
||||
|
||||
if (clonable) {
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"NODISCARD %s %s_clone(const %s* self) {\n" /* VecT, VecT, VecT */
|
||||
SPACE "%s res = (%s){.buf = (%s*)safe_calloc(self->len, sizeof(%s)), .len = self->len, .capacity = self->len};\n",
|
||||
VecT, VecT, VecT, VecT, VecT, T, T));
|
||||
"NODISCARD Vec%s Vec%s_clone(const Vec%s* self) {\n" /* T, T, T */
|
||||
SPACE "Vec%s res = (Vec%s){.buf = (%s*)safe_calloc(self->len, sizeof(%s)),\n" /* T, T, T, T */
|
||||
SPACE SPACE ".len = self->len, .capacity = self->len};\n",
|
||||
T, T, T, T, T, T, T));
|
||||
if (primitive) {
|
||||
VecU8_append_vec(&res, VecU8_fmt(SPACE "memcpy(res.buf, self->buf, self->len * sizeof(%s));\n", T));
|
||||
} else {
|
||||
@ -84,7 +94,7 @@ NODISCARD VecU8 generate_VecT_struct_and_base_methods(SpanU8 T, bool primitive,
|
||||
}
|
||||
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"void %s_append_vec(%s* self, %s b) {\n" /* VecT, VecT, VecT */
|
||||
"void Vec%s_append_vec(Vec%s* self, Vec%s b) {\n" /* T, T, T */
|
||||
SPACE "size_t new_length = self->len + b.len;\n"
|
||||
SPACE "if (new_length > self->capacity) {\n"
|
||||
SPACE SPACE "size_t new_capacity = Vec_get_new_capacity(self->capacity, new_length);\n"
|
||||
@ -96,17 +106,16 @@ NODISCARD VecU8 generate_VecT_struct_and_base_methods(SpanU8 T, bool primitive,
|
||||
SPACE "}\n"
|
||||
SPACE "self->len = new_length;\n"
|
||||
SPACE "free(b.buf);\n"
|
||||
"}\n\n", VecT, VecT, VecT, T, T));
|
||||
"}\n\n", T, T, T, T, T));
|
||||
|
||||
if (primitive) {
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"NODISCARD %s %s_new_zeroinit(size_t len) {\n" /* VecT, VecT*/
|
||||
SPACE "return (%s){.buf = (%s*)safe_calloc(len, sizeof(%s)), .len = len, .capacity = len};\n" /* VecT, T, T */
|
||||
"NODISCARD Vec%s Vec%s_new_zeroinit(size_t len) {\n" /* T, T */
|
||||
SPACE "return (Vec%s){.buf = (%s*)safe_calloc(len, sizeof(%s)), .len = len, .capacity = len};\n" /* T, T, T */
|
||||
"}\n\n",
|
||||
VecT, VecT, VecT, T, T));
|
||||
T, T, T, T, T));
|
||||
}
|
||||
|
||||
VecU8_drop(g_VecT); // VecT invalidated too
|
||||
return res;
|
||||
}
|
||||
|
||||
@ -229,13 +238,16 @@ void codegen_append_some_span_equal_method(VecU8* res, SpanU8 SpanT) {
|
||||
"}\n\n", SpanT, SpanT, SpanT, SpanT));
|
||||
}
|
||||
|
||||
/* helper function. (SpanT, mod) is either (SpanT "const ") or (MutSpanT, "") */
|
||||
void codegen_append_some_span_struct(VecU8* res, SpanU8 T, SpanU8 SpanT, SpanU8 mod) {
|
||||
/* Helper function. (span_mod, mod) is in {("", "const "), ("Mut", "")} */
|
||||
void codegen_append_some_span_struct(VecU8* res, SpanU8 T, SpanU8 span_mod, SpanU8 mod, bool skip_declaration_gen) {
|
||||
if (!skip_declaration_gen) {
|
||||
VecU8_append_vec(res, VecU8_fmt("typedef struct %sSpan%s %sSpan%s;\n\n", span_mod, T, span_mod, T));
|
||||
}
|
||||
VecU8_append_vec(res, VecU8_fmt(
|
||||
"typedef struct {\n"
|
||||
SPACE "%s%s* data;\n"
|
||||
"struct %sSpan%s {\n" /* span_mod, T */
|
||||
SPACE "%s%s* data;\n" /* mod, T */
|
||||
SPACE "size_t len;\n"
|
||||
"} %s;\n\n", mod, T, SpanT));
|
||||
"};\n\n", span_mod, T, mod, T));
|
||||
}
|
||||
|
||||
/* helper function. (SpanT, mod) is either (SpanT "const ") or (MutSpanT, "") */
|
||||
@ -257,11 +269,19 @@ void codegen_append_some_span_span_method(VecU8* res, SpanU8 SpanT) {
|
||||
"}\n\n", SpanT, SpanT, SpanT, SpanT));
|
||||
}
|
||||
|
||||
NODISCARD VecU8 generate_SpanT_structures(SpanU8 T, bool add_mutable, bool skip_declaration_gen){
|
||||
VecU8 res = VecU8_new();
|
||||
codegen_append_some_span_struct(&res, T, cstr(""), cstr("const "), skip_declaration_gen);
|
||||
if (add_mutable)
|
||||
codegen_append_some_span_struct(&res, T, cstr("Mut"), cstr(""), skip_declaration_gen);
|
||||
return res;
|
||||
}
|
||||
|
||||
/* T must be sized. Option `add_sort` requires option `add_mutable` and method T_less
|
||||
* add_mutable option generates MutSpanT.
|
||||
* add_equal option generates equal method. add_extended option generated extended methods
|
||||
*/
|
||||
NODISCARD VecU8 generate_SpanT_struct_and_methods(
|
||||
NODISCARD VecU8 generate_SpanT_base_methods(
|
||||
SpanU8 T, bool integer, bool add_mutable, bool add_equal, bool add_extended
|
||||
) {
|
||||
VecU8 g_SpanT = VecU8_fmt("Span%s", T);
|
||||
@ -270,9 +290,6 @@ NODISCARD VecU8 generate_SpanT_struct_and_methods(
|
||||
SpanU8 MutSpanT = VecU8_to_span(&g_MutSpanT);
|
||||
VecU8 res = VecU8_new();
|
||||
|
||||
codegen_append_some_span_struct(&res, T, SpanT, cstr("const "));
|
||||
if (add_mutable)
|
||||
codegen_append_some_span_struct(&res, T, MutSpanT, cstr(""));
|
||||
if (add_equal) {
|
||||
codegen_append_some_span_equal_method(&res, SpanT);
|
||||
if (add_mutable)
|
||||
@ -426,6 +443,8 @@ typedef struct {
|
||||
bool sort;
|
||||
bool collab_vec_span;
|
||||
bool collab_vec_span_extended;
|
||||
|
||||
bool skip_declaration_gen;
|
||||
} util_templates_instantiation_options;
|
||||
|
||||
void util_templates_instantiation_options_fix(util_templates_instantiation_options* op) {
|
||||
@ -453,37 +472,50 @@ void util_templates_instantiation_options_fix(util_templates_instantiation_optio
|
||||
assert(!op->t_primitive || op->t_clonable);
|
||||
}
|
||||
|
||||
NODISCARD VecU8 generate_util_templates_instantiation(util_templates_instantiation_options op) {
|
||||
NODISCARD VecU8 generate_util_templates_instantiation(util_templates_instantiation_options op,
|
||||
bool generate_structures, bool generate_methods) {
|
||||
VecU8 res = VecU8_new();
|
||||
util_templates_instantiation_options_fix(&op);
|
||||
if (op.vec) {
|
||||
VecU8_append_vec(&res, generate_VecT_struct_and_base_methods(op.T, op.t_primitive, op.t_clonable));
|
||||
|
||||
if (generate_structures) {
|
||||
if (op.vec) {
|
||||
VecU8_append_vec(&res, generate_VecT_struct(op.T, op.skip_declaration_gen));
|
||||
}
|
||||
if (op.span) {
|
||||
VecU8_append_vec(&res, generate_SpanT_structures(op.T, op.mut_span, op.skip_declaration_gen));
|
||||
}
|
||||
}
|
||||
if (op.vec_extended) {
|
||||
assert(op.vec);
|
||||
VecU8_append_vec(&res, generate_VecT_trivmove_extended_methods(op.T, op.t_primitive, op.t_clonable));
|
||||
}
|
||||
if (op.vec_equal) {
|
||||
assert(op.vec);
|
||||
VecU8_append_vec(&res, generate_VecT_equal_method(op.T, op.t_integer));
|
||||
}
|
||||
if (op.vec_new_of_size) {
|
||||
assert(op.vec);
|
||||
VecU8_append_vec(&res, generate_VecT_new_of_size_method(op.T));
|
||||
}
|
||||
if (op.span) {
|
||||
VecU8_append_vec(&res, generate_SpanT_struct_and_methods(op.T, op.t_integer, op.mut_span, false, op.span_extended));
|
||||
}
|
||||
if (op.sort) {
|
||||
VecU8_append_vec(&res, generate_span_company_sort_methods(op.T, op.t_integer, op.mut_span, op.vec));
|
||||
}
|
||||
if (op.collab_vec_span) {
|
||||
assert(op.vec && op.span);
|
||||
VecU8_append_vec(&res, generate_SpanT_VecT_trivmove_collab(op.T, op.t_primitive, op.t_clonable, op.mut_span, op.collab_vec_span_extended));
|
||||
if (generate_methods) {
|
||||
if (op.vec) {
|
||||
VecU8_append_vec(&res, generate_VecT_base_methods(op.T, op.t_primitive, op.t_clonable));
|
||||
}
|
||||
if (op.vec_extended) {
|
||||
assert(op.vec);
|
||||
VecU8_append_vec(&res, generate_VecT_trivmove_extended_methods(op.T, op.t_primitive, op.t_clonable));
|
||||
}
|
||||
if (op.vec_equal) {
|
||||
assert(op.vec);
|
||||
VecU8_append_vec(&res, generate_VecT_equal_method(op.T, op.t_integer));
|
||||
}
|
||||
if (op.vec_new_of_size) {
|
||||
assert(op.vec);
|
||||
VecU8_append_vec(&res, generate_VecT_new_of_size_method(op.T));
|
||||
}
|
||||
if (op.span) {
|
||||
VecU8_append_vec(&res, generate_SpanT_base_methods(op.T, op.t_integer, op.mut_span, false, op.span_extended));
|
||||
}
|
||||
if (op.sort) {
|
||||
VecU8_append_vec(&res, generate_span_company_sort_methods(op.T, op.t_integer, op.mut_span, op.vec));
|
||||
}
|
||||
if (op.collab_vec_span) {
|
||||
assert(op.vec && op.span);
|
||||
VecU8_append_vec(&res, generate_SpanT_VecT_trivmove_collab(op.T, op.t_primitive, op.t_clonable, op.mut_span, op.collab_vec_span_extended));
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
/* Does not include .h postfix. .h postfix and `path` prefix have to be added by someone else */
|
||||
NODISCARD VecU8 util_templates_instantiation_get_appropriate_filename(util_templates_instantiation_options op) {
|
||||
util_templates_instantiation_options_fix(&op);
|
||||
return VecU8_fmt("%s%s%s""%s%s",
|
||||
@ -491,38 +523,49 @@ NODISCARD VecU8 util_templates_instantiation_get_appropriate_filename(util_templ
|
||||
(int)op.vec + (int)op.span > 1 ? cstr("_") : cstr(""), op.T);
|
||||
}
|
||||
|
||||
void generate_util_templ_inst_eve_header(SpanU8 layer, SpanU8 bonus_ns, util_templates_instantiation_options op) {
|
||||
generate_SOME_templ_inst_eve_header(layer, bonus_ns, generate_util_templates_instantiation(op),
|
||||
util_templates_instantiation_get_appropriate_filename(op));
|
||||
void generate_util_templ_inst_eve_header(SpanU8 layer, SpanU8 bonus_ns, util_templates_instantiation_options op,
|
||||
bool separate_struct_and_methods) {
|
||||
if (separate_struct_and_methods) {
|
||||
VecU8 name_for_structures = VecU8_fmt("%v_struct", util_templates_instantiation_get_appropriate_filename(op));
|
||||
VecU8 name_for_methods = VecU8_fmt("%v_methods", util_templates_instantiation_get_appropriate_filename(op));
|
||||
generate_SOME_templ_inst_eve_header(layer, bonus_ns, generate_util_templates_instantiation(op, true, false),
|
||||
name_for_structures);
|
||||
generate_SOME_templ_inst_eve_header(layer, bonus_ns, generate_util_templates_instantiation(op, false, true),
|
||||
name_for_methods);
|
||||
} else {
|
||||
generate_SOME_templ_inst_eve_header(layer, bonus_ns, generate_util_templates_instantiation(op, true, true),
|
||||
util_templates_instantiation_get_appropriate_filename(op));
|
||||
}
|
||||
}
|
||||
|
||||
void generate_eve_span_company_for_primitive(SpanU8 layer, SpanU8 ns, SpanU8 T, bool with_vector, bool with_span) {
|
||||
generate_util_templ_inst_eve_header(layer, ns, (util_templates_instantiation_options){
|
||||
.T = T,
|
||||
.t_primitive = true, .vec = with_vector, .span = with_span, .collab_vec_span = with_vector && with_span
|
||||
});
|
||||
}, false);
|
||||
}
|
||||
|
||||
void generate_eve_span_company_for_non_primitive_clonable(SpanU8 layer, SpanU8 ns, SpanU8 T, bool with_vector, bool with_span) {
|
||||
generate_util_templ_inst_eve_header(layer, ns, (util_templates_instantiation_options){
|
||||
.T = T,
|
||||
.t_clonable = true, .vec = with_vector, .span = with_span, .collab_vec_span = with_vector && with_span
|
||||
});
|
||||
}, false);
|
||||
}
|
||||
|
||||
void generate_eve_span_company_for_non_primitive_non_clonable(SpanU8 layer, SpanU8 ns, SpanU8 T, bool with_vector, bool with_span) {
|
||||
generate_util_templ_inst_eve_header(layer, ns, (util_templates_instantiation_options){
|
||||
.T = T,
|
||||
.vec = with_vector, .span = with_span, .collab_vec_span = with_vector && with_span
|
||||
});
|
||||
}, false);
|
||||
}
|
||||
|
||||
|
||||
void generate_util_templ_inst_guarded_header(
|
||||
SpanU8 layer, SpanU8 bonus_ns, SpanU8 dependencies, util_templates_instantiation_options op
|
||||
) {
|
||||
generate_SOME_templ_inst_guarded_header(layer, bonus_ns, VecU8_fmt("%v%s\n",
|
||||
codegen_include_relative_to_root(bonus_ns, cstr("src/l1/core/util.h")), dependencies),
|
||||
generate_util_templates_instantiation(op), util_templates_instantiation_get_appropriate_filename(op));
|
||||
generate_util_templates_instantiation(op, true, true), util_templates_instantiation_get_appropriate_filename(op));
|
||||
}
|
||||
|
||||
void generate_guarded_span_company_for_primitive(
|
||||
@ -552,6 +595,7 @@ void generate_guarded_span_company_for_non_primitive_non_clonable(
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
NODISCARD VecU8 get_ResultType_inst_name(SpanU8 OkT, SpanU8 ErrT){
|
||||
bool ok_t_void = OkT.len == 0;
|
||||
bool err_t_void = ErrT.len == 0;
|
||||
|
||||
@ -102,6 +102,12 @@ void S64_stringification_into_buf(S64 x, VecU8* targ){
|
||||
}
|
||||
}
|
||||
|
||||
VecU8 S64_stringification(S64 x){
|
||||
VecU8 res = VecU8_new();
|
||||
S64_stringification_into_buf(x, &res);
|
||||
return res;
|
||||
}
|
||||
|
||||
size_t U64_stringification_get_length(U64 x){
|
||||
if (x == 0)
|
||||
return 1;
|
||||
@ -135,6 +141,12 @@ void U64_stringification_into_buf(U64 x, VecU8* targ){
|
||||
}
|
||||
}
|
||||
|
||||
VecU8 U64_stringification(U64 x){
|
||||
VecU8 res = VecU8_new();
|
||||
U64_stringification_into_buf(x, &res);
|
||||
return res;
|
||||
}
|
||||
|
||||
/* %s - SpanU8
|
||||
* %v - VecU8
|
||||
* %u - U64
|
||||
@ -253,11 +265,78 @@ U32 SpanU8_decode_as_utf8(SpanU8* rem){
|
||||
}
|
||||
|
||||
bool SpanU8_is_prefix(SpanU8 a, SpanU8 str){
|
||||
return str.len >= a.len && SpanU8_cont_equal(a, (SpanU8){str.data, a.len});
|
||||
if (str.len < a.len)
|
||||
return false;
|
||||
for (size_t i = 0; i < a.len; i++) {
|
||||
if (a.data[i] != str.data[i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SpanU8_is_postfix(SpanU8 a, SpanU8 str){
|
||||
return str.len >= a.len && SpanU8_cont_equal(a, (SpanU8){str.data + str.len - a.len, a.len});
|
||||
if (str.len < a.len)
|
||||
return false;
|
||||
for (size_t i = 0; i < a.len; i++) {
|
||||
if (a.data[i] != str.data[str.len - a.len + i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// todo: automatically generate such methods for vectors of nice types
|
||||
bool SpanU8_less_SpanU8(SpanU8 a, SpanU8 b){
|
||||
size_t i = 0;
|
||||
while (i < a.len && i < b.len) {
|
||||
if (a.data[i] < b.data[i])
|
||||
return true;
|
||||
if (b.data[i] < a.data[i])
|
||||
return false;
|
||||
i++;
|
||||
}
|
||||
/* If i < b->len, then a is eigen-prefix of b, which means a < b
|
||||
* Or... i < a->len, and this means b is eigen-prefix of a => a > b
|
||||
* Or... a == b . Here we also return false */
|
||||
return i < b.len;
|
||||
}
|
||||
|
||||
bool VecU8_less_VecU8(const VecU8* a, const VecU8* b){
|
||||
return SpanU8_less_SpanU8(VecU8_to_span(a), VecU8_to_span(b));
|
||||
}
|
||||
|
||||
char digit_to_big_hex(U32 d){
|
||||
assert(d < 16);
|
||||
return d >= 10 ? (char)('A' + d - 10) : (char)('0' + d);
|
||||
}
|
||||
|
||||
char digit_to_small_hex(U32 d){
|
||||
assert(d < 16);
|
||||
return d >= 10 ? (char)('a' + d - 10) : (char)('0' + d);
|
||||
}
|
||||
|
||||
static_assert(0b11000000 == 0xC0 && 0b10000000 == 0x80 && 0b00111111 == 0x3F, "asdasda");
|
||||
|
||||
/* Some bytes (encoding codepoint U) will be appended to str. Utf-8 works only with codepoints below (1u << 24) */
|
||||
void VecU8_encode_as_utf8(VecU8* str, U32 U){
|
||||
if (U < (1u << 7)) {
|
||||
VecU8_append(str, (U8)U);
|
||||
} else if (U < (1u << 11)) {
|
||||
VecU8_append_span(str, (SpanU8){(U8[]){
|
||||
0xC0 | (U8)(U >> 6), 0x80 | (U8)(U & 0x3F)
|
||||
}, 2});
|
||||
} else if (U < (1u << 17)) {
|
||||
VecU8_append_span(str, (SpanU8){(U8[]){
|
||||
0xC0 | (U8)(U >> 12), 0x80 | (U8)((U >> 6) & 0x3F), (U8)(U & 0x3F)
|
||||
}, 3});
|
||||
} else {
|
||||
/* U < (1u << 24) */
|
||||
VecU8_append_span(str, (SpanU8){(U8[]){
|
||||
0xC0 | (U8)(U >> 18), 0x80 | (U8)((U >> 12) & 0x3F), 0x80 | (U8)((U >> 6) & 0x3F), (U8)(U & 0x3F)
|
||||
}, 4});
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@ -17,9 +17,16 @@ void generate_l1_5_template_instantiation_for_base_types(){
|
||||
generate_rbtree_Set_templ_inst_guarded_header(l, ns, cstr(""), (set_instantiation_op){
|
||||
.T = cstr("S64"), .t_integer = true }, true);
|
||||
|
||||
// todo: move vector declaration HERE
|
||||
// todo: move vector declaration HERE (might wait)
|
||||
generate_buf_rbtree_Map_templ_inst_guarded_header(l, ns, cstr("#include \"../../gen/l1/VecKVPU64ToU64.h\"\n"),
|
||||
(map_instantiation_op){.K = cstr("U64"), .k_integer = true, .V = cstr("U64"), .v_integer = true,});
|
||||
|
||||
// todo: implement recursion for heap-allocated red-black tree, to make json dictionary clonable
|
||||
generate_rbtree_Map_templ_inst_eve_header(l, ns, (map_instantiation_op){
|
||||
.K = cstr("VecU8"), .k_clonable = true,
|
||||
.V = cstr("Json"), .v_clonable = false,
|
||||
.skip_declaration_gen = true,
|
||||
}, false, true);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@ -9,7 +9,7 @@ void generate_l1_5_lucy_headers(){
|
||||
generate_buf_rbtree_Map_templ_inst_eve_header(l, ns, (map_instantiation_op){
|
||||
.K = cstr("U32"), .k_integer = true, .V = cstr("LucyStoredGlyph"), .v_primitive = true});
|
||||
generate_rbtree_Map_templ_inst_eve_header(l, ns, (map_instantiation_op){
|
||||
.K = cstr("U32"), .k_integer = true, .V = cstr("LucyFaceFixedSize")}, true);
|
||||
.K = cstr("U32"), .k_integer = true, .V = cstr("LucyFaceFixedSize")}, true, false);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -46,6 +46,7 @@ typedef struct {
|
||||
|
||||
bool at, mat;
|
||||
bool pop, pop_substitute;
|
||||
bool skip_declaration_gen;
|
||||
} map_instantiation_op;
|
||||
|
||||
void map_instantiation_op_fix(map_instantiation_op* self){
|
||||
@ -67,7 +68,7 @@ void map_instantiation_op_fix(map_instantiation_op* self){
|
||||
|
||||
|
||||
/* --- Sharing is caring --- */
|
||||
/* Assuming A nd B are passed as intended */
|
||||
/* Assuming A and B are passed as intended */
|
||||
NODISCARD VecU8 codegen_rbtree_map__less(map_instantiation_op op, VecU8 A, VecU8 B){
|
||||
if (op.guest_data_T.len > 0) {
|
||||
assert(op.alternative_less.len > 0);
|
||||
@ -77,7 +78,7 @@ NODISCARD VecU8 codegen_rbtree_map__less(map_instantiation_op op, VecU8 A, VecU8
|
||||
return VecU8_fmt("%s(%v, %v)", op.alternative_less, A, B);
|
||||
if (op.k_integer)
|
||||
return VecU8_fmt("%v < %v", A, B);
|
||||
return VecU8_fmt("%s_less_%s(%v %v)", op.K, op.K, A, B);
|
||||
return VecU8_fmt("%s_less_%s(%v, %v)", op.K, op.K, A, B);
|
||||
}
|
||||
|
||||
NODISCARD VecU8 codegen_rbtree_map__exp_passing_key_val(map_instantiation_op op){
|
||||
|
||||
@ -18,14 +18,18 @@ NODISCARD VecU8 codegen_buf_rbtree_map__exp_passing_cur_key(map_instantiation_op
|
||||
void codegen_append_buff_rbtree_map__structure_and_simplest_methods(
|
||||
VecU8* res, map_instantiation_op op, SpanU8 set, SpanU8 TT
|
||||
){
|
||||
if (!op.skip_declaration_gen) {
|
||||
VecU8_append_vec(res, VecU8_fmt("typedef struct %s %s;\n\n", set, set));
|
||||
}
|
||||
|
||||
VecU8_append_vec(res, VecU8_fmt(
|
||||
"typedef struct {\n"
|
||||
"struct %s{\n"
|
||||
SPACE "VecBufRBTreeNode tree;\n"
|
||||
SPACE "U64 root;\n"
|
||||
SPACE "Vec%s el;\n"
|
||||
"%v"
|
||||
"} %s;\n\n",
|
||||
TT, op.guest_data_T.len > 0 ? VecU8_fmt(SPACE "%s guest;\n", op.guest_data_T) : vcstr(""), set));
|
||||
"};\n\n",
|
||||
set, TT, op.guest_data_T.len > 0 ? VecU8_fmt(SPACE "%s guest;\n", op.guest_data_T) : vcstr("")));
|
||||
|
||||
if (op.guest_data_T.len > 0) {
|
||||
VecU8_append_vec(res, VecU8_fmt(
|
||||
|
||||
@ -28,18 +28,22 @@ NODISCARD VecU8 codegen_rbtree_map__exp_passing_cur_key(map_instantiation_op op)
|
||||
return VecU8_fmt("%s" "((%v*)cur)->key", op.k_integer ? cstr("") : cstr("&"), codegen_rbtree__node_struct_name(op));
|
||||
}
|
||||
|
||||
void codegen_append_rbtree_map__structure_and_simplest_methods(
|
||||
VecU8* res, map_instantiation_op op, SpanU8 set, SpanU8 TT
|
||||
){
|
||||
void codegen_append_rbtree_map__structure(VecU8* res, map_instantiation_op op, SpanU8 set){
|
||||
if (!op.skip_declaration_gen) {
|
||||
VecU8_append_vec(res, VecU8_fmt("typedef struct %s %s;\n\n", set, set));
|
||||
}
|
||||
|
||||
VecU8_append_vec(res, VecU8_fmt(
|
||||
"typedef struct {\n"
|
||||
"struct %s {\n"
|
||||
SPACE "RBTreeNode* root;\n"
|
||||
SPACE "RBTreeNode* NIL;\n"
|
||||
"%v" /* "" / guest field */
|
||||
"} %s;\n\n",
|
||||
op.guest_data_T.len == 0 ? vcstr("") : VecU8_fmt("%s guest;\n", op.guest_data_T),
|
||||
set));
|
||||
"};\n\n",
|
||||
set,
|
||||
op.guest_data_T.len == 0 ? vcstr("") : VecU8_fmt("%s guest;\n", op.guest_data_T)));
|
||||
}
|
||||
|
||||
void codegen_append_rbtree_map__simplest_methods(VecU8* res, map_instantiation_op op, SpanU8 set, SpanU8 TT){
|
||||
VecU8_append_vec(res, VecU8_fmt(
|
||||
"NODISCARD %s %s_new(" "%v" ") {\n" /* set, set, "" / GT guest */
|
||||
/* Only color field initialization is important (should be 0) */
|
||||
@ -290,6 +294,12 @@ void codegen_append_rbtree_map__structure_and_simplest_methods(
|
||||
"}\n\n",
|
||||
set, set, codegen_rbtree_map__taking_ref_k_argument(op),
|
||||
TT, set, set));
|
||||
|
||||
VecU8_append_vec(res, VecU8_fmt(
|
||||
"bool %s_empty(const %s* self){\n" /* set, set */
|
||||
SPACE "return self->root == self->NIL;\n"
|
||||
"}\n\n",
|
||||
set, set));
|
||||
}
|
||||
|
||||
|
||||
@ -312,7 +322,8 @@ NODISCARD VecU8 generate_rbtree_Set_template_instantiation(set_instantiation_op
|
||||
VecU8 set_g = get_name_of_rbtree_set_structure(op);
|
||||
if (generate_node_struct)
|
||||
VecU8_append_vec(&res, codegen_rbtree__node_structure(map_op));
|
||||
codegen_append_rbtree_map__structure_and_simplest_methods(&res, map_op, VecU8_to_span(&set_g), op.T);
|
||||
codegen_append_rbtree_map__structure(&res, map_op, VecU8_to_span(&set_g));
|
||||
codegen_append_rbtree_map__simplest_methods(&res, map_op, VecU8_to_span(&set_g), op.T);
|
||||
VecU8_drop(set_g);
|
||||
return res;
|
||||
}
|
||||
@ -340,7 +351,8 @@ NODISCARD VecU8 get_name_of_rbtree_map_structure(map_instantiation_op op){
|
||||
return VecU8_fmt("RBTree_Map%sTo%s", op.K, op.V);
|
||||
}
|
||||
|
||||
NODISCARD VecU8 generate_rbtree_Map_template_instantiation(map_instantiation_op op, bool generate_node_struct){
|
||||
NODISCARD VecU8 generate_rbtree_Map_template_instantiation(map_instantiation_op op, bool generate_node_struct,
|
||||
bool generate_map_struct, bool generate_methods){
|
||||
map_instantiation_op_fix(&op);
|
||||
|
||||
VecU8 res = VecU8_new();
|
||||
@ -351,73 +363,89 @@ NODISCARD VecU8 generate_rbtree_Map_template_instantiation(map_instantiation_op
|
||||
|
||||
if (generate_node_struct)
|
||||
VecU8_append_vec(&res, codegen_rbtree__node_structure(op));
|
||||
codegen_append_rbtree_map__structure_and_simplest_methods(&res, op, map, kvp);
|
||||
if (generate_map_struct)
|
||||
codegen_append_rbtree_map__structure(&res, op, map);
|
||||
if (generate_methods) {
|
||||
codegen_append_rbtree_map__simplest_methods(&res, op, map, kvp);
|
||||
|
||||
if (op.pop_substitute) {
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"%s" "Option%s %s_pop_substitute(%s* self, %s key, %s value) {\n" /* "" / NODISCARD , op.V, map, map, op.K, op.V */
|
||||
/* Using unsafe method with conditional ownership transfer */
|
||||
SPACE "RBTreeNode_%s* col = %s_try_insert(self, key, value);\n" /* kvp, map */
|
||||
SPACE "if (col == NULL) {\n"
|
||||
SPACE SPACE "return None_%s();\n" /* op.V */
|
||||
SPACE "} else {\n"
|
||||
"%v" /* "" / dropping col->key */
|
||||
SPACE SPACE "%s saved = col->value;\n" /* op.V */
|
||||
SPACE SPACE "col->key = key;\n"
|
||||
SPACE SPACE "col->value = value;\n"
|
||||
SPACE SPACE "return Some_%s(saved);\n" /* op.V */
|
||||
SPACE "}\n"
|
||||
"}\n\n",
|
||||
op.v_primitive ? cstr("") : cstr("NODISCARD "), op.V, map, map, op.K, op.V,
|
||||
kvp, map, op.V,
|
||||
op.k_primitive ? vcstr("") : VecU8_fmt(SPACE SPACE"%s_drop(col->key);\n", op.K),
|
||||
op.V, op.V));
|
||||
if (op.pop_substitute) {
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"%s" "Option%s %s_pop_substitute(%s* self, %s key, %s value) {\n" /* "" / NODISCARD , op.V, map, map, op.K, op.V */
|
||||
/* Using unsafe method with conditional ownership transfer */
|
||||
SPACE "RBTreeNode_%s* col = %s_try_insert(self, key, value);\n" /* kvp, map */
|
||||
SPACE "if (col == NULL) {\n"
|
||||
SPACE SPACE "return None_%s();\n" /* op.V */
|
||||
SPACE "} else {\n"
|
||||
"%v" /* "" / dropping col->key */
|
||||
SPACE SPACE "%s saved = col->value;\n" /* op.V */
|
||||
SPACE SPACE "col->key = key;\n"
|
||||
SPACE SPACE "col->value = value;\n"
|
||||
SPACE SPACE "return Some_%s(saved);\n" /* op.V */
|
||||
SPACE "}\n"
|
||||
"}\n\n",
|
||||
op.v_primitive ? cstr("") : cstr("NODISCARD "), op.V, map, map, op.K, op.V,
|
||||
kvp, map, op.V,
|
||||
op.k_primitive ? vcstr("") : VecU8_fmt(SPACE SPACE"%s_drop(col->key);\n", op.K),
|
||||
op.V, op.V));
|
||||
}
|
||||
if (!op.v_primitive) {
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"bool %s_erase_substitute(%s* self, %s key, %s value) {\n" /* map, map, op.K, op.V */
|
||||
SPACE "RBTreeNode_%s* col = %s_try_insert(self, key, value);\n" /* kvp, map */
|
||||
SPACE "if (col == NULL)\n"
|
||||
SPACE SPACE "return true;\n"
|
||||
"%v" "%v" /* "" / op.K_drop(col->key), "" / op.V_drop(col->value) */
|
||||
SPACE "col->key = key;\n"
|
||||
SPACE "col->value = value;\n"
|
||||
SPACE "return false;\n"
|
||||
"}\n\n",
|
||||
map, map, op.K, op.V, kvp, map,
|
||||
op.k_primitive ? vcstr("") : VecU8_fmt(SPACE "%s_drop(col->key);\n", op.K),
|
||||
op.v_primitive ? vcstr("") : VecU8_fmt(SPACE "%s_drop(col->value);\n", op.V)));
|
||||
}
|
||||
|
||||
if (op.pop){
|
||||
// todo: write _pop_by_it
|
||||
|
||||
// todo: rewrite pop using _pop_by_it
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"Option%s %s_pop(%s* self, %v key) {\n" /* op.V, map, map, taking_ref_k_argument */
|
||||
SPACE "RBTreeNode_%s* v = %s_find(self, key);\n" /* kvp, map */
|
||||
SPACE "if (v == NULL)\n"
|
||||
SPACE SPACE "return None_%s();\n" /* op.V */
|
||||
"%v" /* "" / op.K_drop(v->key) */
|
||||
"%s saved = v->value;\n" /* op.V */
|
||||
SPACE "RBTree_erase_empty_by_iter(&self->root, self->NIL, (RBTreeNode*)v);\n"
|
||||
SPACE "free(v);\n"
|
||||
SPACE "return Some_%s(saved);\n" /* op.V */
|
||||
"}\n\n",
|
||||
op.V, map, map, codegen_rbtree_map__taking_ref_k_argument(op),
|
||||
kvp, map, op.V,
|
||||
op.k_primitive ? vcstr("") : VecU8_fmt(SPACE "%s_drop(v->key);\n", op.K),
|
||||
op.V, op.V));
|
||||
}
|
||||
// todo: write generator for methods _at and _mat
|
||||
}
|
||||
if (!op.v_primitive) {
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"bool %s_erase_substitute(%s* self, %s key, %s value) {\n" /* map, map, op.K, op.V */
|
||||
SPACE "RBTreeNode_%s* col = %s_try_insert(self, key, value);\n" /* kvp, map */
|
||||
SPACE "if (col == NULL)\n"
|
||||
SPACE SPACE "return true;\n"
|
||||
"%v" "%v" /* "" / op.K_drop(col->key), "" / op.V_drop(col->value) */
|
||||
SPACE "col->key = key;\n"
|
||||
SPACE "col->value = value;\n"
|
||||
SPACE "return false;\n"
|
||||
"}\n\n",
|
||||
map, map, op.K, op.V, kvp, map,
|
||||
op.k_primitive ? vcstr("") : VecU8_fmt(SPACE "%s_drop(col->key);\n", op.K),
|
||||
op.v_primitive ? vcstr("") : VecU8_fmt(SPACE "%s_drop(col->value);\n", op.V)));
|
||||
}
|
||||
|
||||
if (op.pop){
|
||||
// todo: write _pop_by_it
|
||||
|
||||
// todo: rewrite pop using _pop_by_it
|
||||
VecU8_append_vec(&res, VecU8_fmt(
|
||||
"Option%s %s_pop(%s* self, %v key) {\n" /* op.V, map, map, taking_ref_k_argument */
|
||||
SPACE "RBTreeNode_%s* v = %s_find(self, key);\n" /* kvp, map */
|
||||
SPACE "if (v == NULL)\n"
|
||||
SPACE SPACE "return None_%s();\n" /* op.V */
|
||||
"%v" /* "" / op.K_drop(v->key) */
|
||||
"%s saved = v->value;\n" /* op.V */
|
||||
SPACE "RBTree_erase_empty_by_iter(&self->root, self->NIL, (RBTreeNode*)v);\n"
|
||||
SPACE "free(v);\n"
|
||||
SPACE "return Some_%s(saved);\n" /* op.V */
|
||||
"}\n\n",
|
||||
op.V, map, map, codegen_rbtree_map__taking_ref_k_argument(op),
|
||||
kvp, map, op.V,
|
||||
op.k_primitive ? vcstr("") : VecU8_fmt(SPACE "%s_drop(v->key);\n", op.K),
|
||||
op.V, op.V));
|
||||
}
|
||||
// todo: write generator for methods _at and _mat
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
void generate_rbtree_Map_templ_inst_eve_header(SpanU8 layer, SpanU8 bonus_ns, map_instantiation_op op,
|
||||
bool generate_node_struct) {
|
||||
generate_SOME_templ_inst_eve_header(layer, bonus_ns,
|
||||
generate_rbtree_Map_template_instantiation(op, generate_node_struct), get_name_of_rbtree_map_structure(op));
|
||||
bool generate_node_struct, bool separate_struct_and_methods) {
|
||||
if (separate_struct_and_methods) {
|
||||
assert(!generate_node_struct);
|
||||
VecU8 name_for_struct = VecU8_fmt("%v_struct", get_name_of_rbtree_map_structure(op));
|
||||
VecU8 name_for_method = VecU8_fmt("%v_method", get_name_of_rbtree_map_structure(op));
|
||||
generate_SOME_templ_inst_eve_header(layer, bonus_ns,
|
||||
generate_rbtree_Map_template_instantiation(op, false, true, false),
|
||||
name_for_struct);
|
||||
generate_SOME_templ_inst_eve_header(layer, bonus_ns,
|
||||
generate_rbtree_Map_template_instantiation(op, false, false, true),
|
||||
name_for_method);
|
||||
} else {
|
||||
generate_SOME_templ_inst_eve_header(layer, bonus_ns,
|
||||
generate_rbtree_Map_template_instantiation(op, generate_node_struct, true, true),
|
||||
get_name_of_rbtree_map_structure(op));
|
||||
}
|
||||
}
|
||||
|
||||
void generate_rbtree_Map_templ_inst_guarded_header(
|
||||
@ -426,8 +454,8 @@ void generate_rbtree_Map_templ_inst_guarded_header(
|
||||
VecU8 all_dependencies = VecU8_fmt("%v%s",
|
||||
codegen_include_relative_to_root(bonus_ns, cstr("src/l1_5/core/rb_tree_node.h")), dependencies);
|
||||
generate_SOME_templ_inst_guarded_header(layer, bonus_ns, all_dependencies,
|
||||
generate_rbtree_Map_template_instantiation(op, generate_node_struct), get_name_of_rbtree_map_structure(op));
|
||||
generate_rbtree_Map_template_instantiation(op, generate_node_struct, true, true),
|
||||
get_name_of_rbtree_map_structure(op));
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@ -4,17 +4,6 @@
|
||||
#include "../../l1/core/VecU8_as_str.h"
|
||||
#include <math.h>
|
||||
|
||||
void SpanU8_parsing_expect_char(SpanU8* rem, char ch){
|
||||
if (rem->len == 0) {
|
||||
abortf("Unexpected EOF. Syntax error\n");
|
||||
}
|
||||
if (*rem->data != (U8)ch) {
|
||||
abortf("Expected %d, got %d. Syntax error\n", (int)(*rem->data), (int)ch);
|
||||
}
|
||||
rem->data++;
|
||||
rem->len--;
|
||||
}
|
||||
|
||||
/* if `expected` is prefix of `rem`, `rem` will be advanced by |`expected`| and true will be returned.
|
||||
* Otherwise false is returned and `rem` is untouched */
|
||||
bool SpanU8_parsing_try_read_prefix(SpanU8* rem, SpanU8 expected){
|
||||
@ -29,13 +18,18 @@ bool SpanU8_parsing_try_read_prefix(SpanU8* rem, SpanU8 expected){
|
||||
return false;
|
||||
}
|
||||
|
||||
void SpanU8_parsing_skip_char(SpanU8* rem){
|
||||
assert(rem->len > 0);
|
||||
rem->data++;
|
||||
rem->len--;
|
||||
}
|
||||
|
||||
bool SpanU8_parsing_try_read_char(SpanU8* rem, char ch){
|
||||
if (rem->len == 0) {
|
||||
return false;
|
||||
}
|
||||
if (rem->data[0] == (U8)ch) {
|
||||
rem->data++;
|
||||
rem->len--;
|
||||
SpanU8_parsing_skip_char(rem);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@ -50,19 +44,13 @@ void SpanU8_parsing_skip_entire_line(SpanU8* rem){
|
||||
}
|
||||
}
|
||||
|
||||
void SpanU8_parsing_skip_char(SpanU8* rem){
|
||||
assert(rem->len > 0);
|
||||
rem->data++;
|
||||
rem->len--;
|
||||
}
|
||||
|
||||
bool SpanU8_parsing_is_char_ahead(SpanU8* rem, char ch){
|
||||
return rem->len > 0 ? rem->data[0] == (U8)ch : false;
|
||||
}
|
||||
|
||||
/* Time to learn how to read integers */
|
||||
|
||||
/* returns positive on error, returns 0 on success */
|
||||
/* Returns positive on error, 0 on success, rem_ret is untouched on error */
|
||||
int SpanU8_read_U64(SpanU8* rem_ret, U64* res_ret){
|
||||
SpanU8 rem = *rem_ret;
|
||||
U64 x = 0;
|
||||
@ -102,6 +90,7 @@ U64 SpanU64_expect_read_U64(SpanU8* rem){
|
||||
return x;
|
||||
}
|
||||
|
||||
/* Returns positive on error, 0 on success, rem_ret is untouched on error */
|
||||
int SpanU8_read_S64(SpanU8* rem_ret, S64* ret){
|
||||
SpanU8 rem = *rem_ret;
|
||||
U64 x = 0;
|
||||
@ -156,7 +145,7 @@ int SpanU8_read_S64(SpanU8* rem_ret, S64* ret){
|
||||
}
|
||||
|
||||
|
||||
/* returns positive int on error, 0 on success */
|
||||
/* returns positive int on error, 0 on success, rem_ret is untouched on error */
|
||||
int SpanU8_read_float(SpanU8* rem_ret, float* res_ret){
|
||||
SpanU8 rem = *rem_ret;
|
||||
|
||||
@ -187,8 +176,10 @@ int SpanU8_read_float(SpanU8* rem_ret, float* res_ret){
|
||||
res = (res * 10 + d);
|
||||
}
|
||||
saw_digit = true;
|
||||
} else if (ch == 'e') {
|
||||
} else if (ch == 'e' || ch == 'E') {
|
||||
SpanU8_parsing_skip_char(&rem);
|
||||
if (SpanU8_parsing_is_char_ahead(&rem, '+'))
|
||||
SpanU8_parsing_skip_char(&rem);
|
||||
S64 exp;
|
||||
int ret = SpanU8_read_S64(&rem, &exp);
|
||||
if (ret)
|
||||
@ -227,4 +218,41 @@ float SpanU8_expect_read_float(SpanU8* rem){
|
||||
return x;
|
||||
}
|
||||
|
||||
void SpanU8_parsing_skip_spaces(SpanU8* rem){
|
||||
while (rem->len) {
|
||||
U8 ch = *rem->data;
|
||||
if (!(ch == '\t' || ch == ' ' || ch == '\n' || ch == '\r'))
|
||||
break;
|
||||
SpanU8_parsing_skip_char(rem);
|
||||
}
|
||||
}
|
||||
|
||||
bool is_hex_char(char ch){
|
||||
return ('0' <= ch && ch <= '9') || ('a' <= ch && ch <= 'f') || ('A' <= ch && ch <= 'F');
|
||||
}
|
||||
|
||||
static_assert('a' > 'A', "ASCII check");
|
||||
static_assert('A' > '0', "ASCII check");
|
||||
|
||||
U32 char_to_hex_digit(char ch){
|
||||
if (ch >= 'a')
|
||||
return ch - 'a' + 10;
|
||||
if (ch >= 'A')
|
||||
return ch - 'A' + 10;
|
||||
return ch - '0';
|
||||
}
|
||||
|
||||
/* Should return true on success */
|
||||
bool SpanU8_parsing_try_read_hex_digit(SpanU8* rem, U32* ret){
|
||||
if (rem->len == 0)
|
||||
return false;
|
||||
char ch = (char)rem->data[0];
|
||||
if (is_hex_char(ch)) {
|
||||
*ret = char_to_hex_digit(ch);
|
||||
SpanU8_parsing_skip_char(rem);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@ -895,19 +895,19 @@ VecVecs64vec2 generate_funny_polygon(){
|
||||
|
||||
/* We are on l2 */
|
||||
int gen_assets_for_r4() {
|
||||
// mkdir_nofail("l2/models");
|
||||
// mkdir_nofail("l2/textures");
|
||||
// mkdir_nofail("l2/textures/r4");
|
||||
// r4_asset_gen_generic_mesh_one_fourth_of_a_cylinder_2(10, 2, 6);
|
||||
// alice_write_shiny_mesh_to_file(generate_shiny_cube((vec3){0.6f, 0.6f, 0.7f}), vcstr("l2/models/cube.AliceShinyMesh"));
|
||||
// alice_write_shiny_mesh_to_file(generate_shiny_lamp(0.3f, 0.13f, 0.19f), vcstr("l2/models/lamp.AliceShinyMesh"));
|
||||
// r4_asset_gen_generic_mesh_quad(10, 10, vcstr("l2/models/quad.AliceGenericMesh"));
|
||||
// r4_asset_gen_generic_mesh_cylinder(200, 0.4f, 0.17f, 30, vcstr("l2/models/puck.AliceGenericMesh"),
|
||||
// vcstr("l2/textures/puck_TEMPLATE.png"), vcstr("l2/textures/puck_NORMAL.png"));
|
||||
// r4_asset_gen_generic_mesh_cylinder(100, 0.04f, 1.5f, 4, vcstr("l2/models/stick.AliceGenericMesh"),
|
||||
// vcstr("l2/textures/stick_TEMPLATE.png"), vcstr("l2/textures/stick_NORMAL.png"));
|
||||
// r4_generate_flat_normal_map(vcstr("l2/textures/flat_NORMAL.png"));
|
||||
// generate_single_pixel_gray_tex(vcstr("l2/textures/no_SPECULAR.png"), 0);
|
||||
mkdir_nofail("l2/models");
|
||||
mkdir_nofail("l2/textures");
|
||||
mkdir_nofail("l2/textures/r4");
|
||||
r4_asset_gen_generic_mesh_one_fourth_of_a_cylinder_2(10, 2, 6);
|
||||
alice_write_shiny_mesh_to_file(generate_shiny_cube((vec3){0.6f, 0.6f, 0.7f}), vcstr("l2/models/cube.AliceShinyMesh"));
|
||||
alice_write_shiny_mesh_to_file(generate_shiny_lamp(0.3f, 0.13f, 0.19f), vcstr("l2/models/lamp.AliceShinyMesh"));
|
||||
r4_asset_gen_generic_mesh_quad(10, 10, vcstr("l2/models/quad.AliceGenericMesh"));
|
||||
r4_asset_gen_generic_mesh_cylinder(200, 0.4f, 0.17f, 30, vcstr("l2/models/puck.AliceGenericMesh"),
|
||||
vcstr("l2/textures/puck_TEMPLATE.png"), vcstr("l2/textures/puck_NORMAL.png"));
|
||||
r4_asset_gen_generic_mesh_cylinder(100, 0.04f, 1.5f, 4, vcstr("l2/models/stick.AliceGenericMesh"),
|
||||
vcstr("l2/textures/stick_TEMPLATE.png"), vcstr("l2/textures/stick_NORMAL.png"));
|
||||
r4_generate_flat_normal_map(vcstr("l2/textures/flat_NORMAL.png"));
|
||||
generate_single_pixel_gray_tex(vcstr("l2/textures/no_SPECULAR.png"), 0);
|
||||
{ /* Just a test */
|
||||
VecVecs64vec2 P = generate_funny_polygon();
|
||||
r4_asset_gen_generic_mesh_horizontal_polygon(&P, (mat3x2){.x.x = 1, .y.y = 1},
|
||||
|
||||
95
src/l2/core/json.h
Normal file
95
src/l2/core/json.h
Normal file
@ -0,0 +1,95 @@
|
||||
#ifndef prototype1_src_l2_core_json_h
|
||||
#define prototype1_src_l2_core_json_h
|
||||
|
||||
#include "../../l1/core/VecU8_as_str.h"
|
||||
#include "../../l1_5/core/rb_tree_node.h"
|
||||
|
||||
typedef struct Json Json;
|
||||
|
||||
typedef struct VecJson VecJson;
|
||||
typedef struct RBTree_MapVecU8ToJson RBTree_MapVecU8ToJson;
|
||||
|
||||
#include "../../../gen/l1/eve/VecJson_struct.h"
|
||||
#include "../../../gen/l1_5/eve/RBTree_MapVecU8ToJson_struct.h"
|
||||
|
||||
typedef enum {
|
||||
Json_integer,
|
||||
Json_float,
|
||||
Json_dict,
|
||||
Json_arr,
|
||||
Json_str,
|
||||
Json_false,
|
||||
Json_true,
|
||||
Json_none,
|
||||
} Json_variant;
|
||||
|
||||
struct Json{
|
||||
Json_variant variant;
|
||||
union {
|
||||
S64 integer;
|
||||
float float_num;
|
||||
RBTree_MapVecU8ToJson dict;
|
||||
VecJson arr;
|
||||
VecU8 str;
|
||||
};
|
||||
};
|
||||
|
||||
typedef struct RBTreeNode_KVPVecU8ToJson {
|
||||
RBTreeNode base;
|
||||
VecU8 key;
|
||||
Json value;
|
||||
} RBTreeNode_KVPVecU8ToJson;
|
||||
|
||||
/* Pulling declarations of methods, defined below */
|
||||
void VecJson_drop(VecJson self);
|
||||
void RBTree_MapVecU8ToJson_drop(RBTree_MapVecU8ToJson self);
|
||||
|
||||
void Json_drop(Json self) {
|
||||
if (self.variant == Json_str) {
|
||||
VecU8_drop(self.str);
|
||||
} else if (self.variant == Json_arr) {
|
||||
VecJson_drop(self.arr);
|
||||
} else if (self.variant == Json_dict) {
|
||||
RBTree_MapVecU8ToJson_drop(self.dict);
|
||||
}
|
||||
}
|
||||
|
||||
#include "../../../gen/l1/eve/VecJson_methods.h"
|
||||
#include "../../../gen/l1_5/eve/RBTree_MapVecU8ToJson_method.h"
|
||||
|
||||
Json Json_from_float(float x){
|
||||
return (Json){.variant = Json_float, .float_num = x};
|
||||
}
|
||||
|
||||
Json Json_from_int(S64 x){
|
||||
return (Json){.variant = Json_float, .integer = x};
|
||||
}
|
||||
|
||||
Json Json_from_VecU8(VecU8 x){
|
||||
return (Json){.variant = Json_str, .str = x};
|
||||
}
|
||||
|
||||
Json Json_from_SpanU8(SpanU8 x){
|
||||
return (Json){.variant = Json_str, .str = VecU8_from_span(x)};
|
||||
}
|
||||
|
||||
Json Json_from_bool(bool x){
|
||||
return (Json){.variant = x ? Json_true : Json_false};
|
||||
}
|
||||
|
||||
const Json Json_None = ((Json){.variant = Json_none});
|
||||
const Json Json_True = ((Json){.variant = Json_true});
|
||||
const Json Json_False = ((Json){.variant = Json_false});
|
||||
|
||||
Json Json_from_VecJson(VecJson arr){
|
||||
return (Json){.variant = Json_arr, .arr = arr};
|
||||
}
|
||||
|
||||
Json Json_from_MapVecU8ToJson(RBTree_MapVecU8ToJson dict){
|
||||
return (Json){.variant = Json_dict, .dict = dict};
|
||||
}
|
||||
|
||||
// Bonus
|
||||
#include "../../../gen/l1/eve/OptionJson.h"
|
||||
|
||||
#endif
|
||||
278
src/l2/core/json_encoded.h
Normal file
278
src/l2/core/json_encoded.h
Normal file
@ -0,0 +1,278 @@
|
||||
#ifndef prototype1_src_l2_core_json_encoded_h
|
||||
#define prototype1_src_l2_core_json_encoded_h
|
||||
|
||||
#include "../../l1_5/core/parsing_string.h"
|
||||
#include "json.h"
|
||||
|
||||
void json_encoding_append_utf16(VecU8* res, U8 codepoint){
|
||||
assert(codepoint < 32);
|
||||
VecU8_append_span(res, cstr("\\u00"));
|
||||
VecU8_append(res, digit_to_big_hex(codepoint >> 4));
|
||||
VecU8_append(res, digit_to_big_hex(codepoint & 0xF));
|
||||
}
|
||||
|
||||
/* Str is being encoded as JSON string literal */
|
||||
void json_encoding_append_string(VecU8* res, const VecU8* str){
|
||||
VecU8_append(res, '"');
|
||||
for (size_t i = 0; i < str->len; i++) {
|
||||
U8 ch = str->buf[i];
|
||||
if (ch == '\t') {
|
||||
VecU8_append_span(res, cstr("\\t"));
|
||||
} else if (ch == '\n') {
|
||||
VecU8_append_span(res, cstr("\\n"));
|
||||
} else if (ch == '\r') {
|
||||
VecU8_append_span(res, cstr("\\r"));
|
||||
} else if (ch <= 31) {
|
||||
json_encoding_append_utf16(res, ch);
|
||||
} else if (ch == '\"') {
|
||||
VecU8_append_span(res, cstr("\\\""));
|
||||
} else if (ch == '\\') {
|
||||
VecU8_append_span(res, cstr("\\\\"));
|
||||
} else {
|
||||
VecU8_append(res, ch);
|
||||
}
|
||||
}
|
||||
VecU8_append(res, '"');
|
||||
}
|
||||
|
||||
/* No prettyprinting */
|
||||
void json_encoding_append_to_str(const Json* obj, VecU8* res){
|
||||
if (obj->variant == Json_false) {
|
||||
VecU8_append_span(res, cstr("false"));
|
||||
} else if (obj->variant == Json_true) {
|
||||
VecU8_append_span(res, cstr("true"));
|
||||
} else if (obj->variant == Json_none) {
|
||||
VecU8_append_span(res, cstr("none"));
|
||||
} else if (obj->variant == Json_integer) {
|
||||
S64_stringification_into_buf(obj->integer, res);
|
||||
} else if (obj->variant == Json_float) {
|
||||
VecU8_append_vec(res, VecU8_format("%f", obj->float_num));
|
||||
} else if (obj->variant == Json_str) {
|
||||
json_encoding_append_string(res, &obj->str);
|
||||
} else if (obj->variant == Json_arr) {
|
||||
VecU8_append(res, '[');
|
||||
const VecJson* arr = &obj->arr;
|
||||
for (size_t i = 0; i < arr->len; i++) {
|
||||
if (i) {
|
||||
VecU8_append_span(res, cstr(", "));
|
||||
}
|
||||
json_encoding_append_to_str(&arr->buf[i], res);
|
||||
}
|
||||
VecU8_append(res, ']');
|
||||
} else if (obj->variant == Json_dict) {
|
||||
VecU8_append(res, '{');
|
||||
bool was = false;
|
||||
for (RBTreeNode_KVPVecU8ToJson* it = RBTree_MapVecU8ToJson_find_min(&obj->dict); it;) {
|
||||
if (was) {
|
||||
VecU8_append_span(res, cstr(", "));
|
||||
}
|
||||
json_encoding_append_string(res, &it->key);
|
||||
VecU8_append_span(res, cstr(": "));
|
||||
json_encoding_append_to_str(&it->value, res);
|
||||
was = true;
|
||||
it = RBTree_MapVecU8ToJson_find_next(&obj->dict, it);
|
||||
}
|
||||
VecU8_append(res, '}');
|
||||
}
|
||||
}
|
||||
|
||||
/* json depth is w => Required stack depth is w frames */
|
||||
VecU8 json_encode(const Json* obj){
|
||||
VecU8 res = VecU8_new();
|
||||
json_encoding_append_to_str(obj, &res);
|
||||
return res;
|
||||
}
|
||||
|
||||
/* Kids had their fun with json encoding. Now it's time for adults to enjoy some parsing */
|
||||
|
||||
|
||||
|
||||
OptionJson json_decoding_h_no_spaces(SpanU8* rem, U32 depth_rem);
|
||||
|
||||
OptionJson json_decoding_h(SpanU8* rem, U32 depth_rem){
|
||||
SpanU8_parsing_skip_spaces(rem);
|
||||
OptionJson x = json_decoding_h_no_spaces(rem, depth_rem);
|
||||
SpanU8_parsing_skip_spaces(rem);
|
||||
return x;
|
||||
}
|
||||
|
||||
/* Returns positive on error, 0 on success */
|
||||
int json_decoding_parse_string(SpanU8* rem, VecU8* ret_str){
|
||||
if (!SpanU8_parsing_try_read_char(rem, '\"')) {
|
||||
return 1;
|
||||
}
|
||||
VecU8 res = VecU8_new();
|
||||
U16 prev_high_surrogate = 0;
|
||||
while (true) {
|
||||
if (rem->len == 0) {
|
||||
VecU8_drop(res);
|
||||
return 1;
|
||||
}
|
||||
U8 ch = rem->data[0];
|
||||
SpanU8_parsing_skip_char(rem);
|
||||
if (ch == '\"') {
|
||||
*ret_str = res;
|
||||
return 0;
|
||||
}
|
||||
if (ch == '\\') {
|
||||
if (rem->len == 0) {
|
||||
VecU8_drop(res);
|
||||
return 2;
|
||||
}
|
||||
ch = rem->data[0];
|
||||
SpanU8_parsing_skip_char(rem);
|
||||
if (ch == '\"' || ch == '\\' || ch == '/') {
|
||||
VecU8_append(&res, ch);
|
||||
} else if (ch == 'b') {
|
||||
VecU8_append(&res, '\b');
|
||||
} else if (ch == 'f') {
|
||||
VecU8_append(&res, '\f');
|
||||
} else if (ch == 'n') {
|
||||
VecU8_append(&res, '\b');
|
||||
} else if (ch == 'r') {
|
||||
VecU8_append(&res, '\r');
|
||||
} else if (ch == 't') {
|
||||
VecU8_append(&res, '\t');
|
||||
} else if (ch == 'u') {
|
||||
U16 cur_word = 0;
|
||||
for (int i = 0; i < 4; i++) {
|
||||
U32 d;
|
||||
if (!SpanU8_parsing_try_read_hex_digit(rem, &d)) {
|
||||
VecU8_drop(res);
|
||||
return 3;
|
||||
}
|
||||
cur_word = (cur_word << 4) | (U16)d;
|
||||
}
|
||||
if (0xDC00 <= cur_word && cur_word < 0xE000) {
|
||||
/* Low surrogate pair */
|
||||
if (prev_high_surrogate == 0) {
|
||||
VecU8_drop(res);
|
||||
return 4;
|
||||
}
|
||||
U32 U = (U32)0x10000 + ((U32)(prev_high_surrogate - 0xD800) << 10) + (U32)(cur_word - 0xDC00);
|
||||
VecU8_encode_as_utf8(&res, U);
|
||||
prev_high_surrogate = 0;
|
||||
} else if (0xD800 <= cur_word && cur_word < 0xDC00) {
|
||||
/* High surrogate pair */
|
||||
prev_high_surrogate = cur_word;
|
||||
} else {
|
||||
prev_high_surrogate = 0;
|
||||
VecU8_encode_as_utf8(&res, (U32)cur_word);
|
||||
}
|
||||
} else {
|
||||
VecU8_drop(res);
|
||||
return 5;
|
||||
}
|
||||
} else {
|
||||
/* We ignore illegal characters in string literals */
|
||||
VecU8_append(&res, ch);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
OptionJson json_decoding_h_no_spaces(SpanU8* rem, U32 depth_rem){
|
||||
if (depth_rem == 0) {
|
||||
return None_Json();
|
||||
}
|
||||
float fl_value;
|
||||
int fl_code = SpanU8_read_float(rem, &fl_value);
|
||||
if (fl_code == 0)
|
||||
return Some_Json(Json_from_float(fl_value));
|
||||
S64 int_value;
|
||||
int int_code = SpanU8_read_S64(rem, &int_value);
|
||||
if (int_code == 0)
|
||||
return Some_Json(Json_from_int(int_value));
|
||||
bool false_code = SpanU8_parsing_try_read_prefix(rem, cstr("false"));
|
||||
if (false_code)
|
||||
return Some_Json(Json_False);
|
||||
bool true_code = SpanU8_parsing_try_read_prefix(rem, cstr("true"));
|
||||
if (true_code)
|
||||
return Some_Json(Json_True);
|
||||
bool none_code = SpanU8_parsing_try_read_prefix(rem, cstr("none"));
|
||||
if (none_code)
|
||||
return Some_Json(Json_None);
|
||||
if (SpanU8_parsing_is_char_ahead(rem, '\"')) {
|
||||
VecU8 str;
|
||||
int str_code = json_decoding_parse_string(rem, &str);
|
||||
if (str_code) {
|
||||
/* str is uninitialized on error */
|
||||
return None_Json();
|
||||
}
|
||||
/* In case of success, str starts owning a VecU8 */
|
||||
return Some_Json(Json_from_VecU8(str));
|
||||
}
|
||||
if (SpanU8_parsing_try_read_char(rem, '[')) {
|
||||
SpanU8_parsing_skip_spaces(rem);
|
||||
VecJson arr = VecJson_new();
|
||||
while (true) {
|
||||
if (SpanU8_parsing_try_read_char(rem, ']')) {
|
||||
return Some_Json(Json_from_VecJson(arr));
|
||||
}
|
||||
if (arr.len > 0) {
|
||||
if (!SpanU8_parsing_try_read_char(rem, ',')) {
|
||||
VecJson_drop(arr);
|
||||
return None_Json();
|
||||
}
|
||||
}
|
||||
OptionJson x = json_decoding_h(rem, depth_rem - 1);
|
||||
if (x.variant == Option_None) {
|
||||
VecJson_drop(arr);
|
||||
return None_Json();
|
||||
}
|
||||
VecJson_append(&arr, x.some);
|
||||
}
|
||||
}
|
||||
if (SpanU8_parsing_try_read_char(rem, '{')) {
|
||||
SpanU8_parsing_skip_spaces(rem);
|
||||
RBTree_MapVecU8ToJson dict = RBTree_MapVecU8ToJson_new();
|
||||
while (true) {
|
||||
if (SpanU8_parsing_try_read_char(rem, '}')) {
|
||||
return Some_Json(Json_from_MapVecU8ToJson(dict));
|
||||
}
|
||||
// todo: add _empty method to rb tree map
|
||||
if (!RBTree_MapVecU8ToJson_empty(&dict)) {
|
||||
if (!SpanU8_parsing_try_read_char(rem, ',')) {
|
||||
RBTree_MapVecU8ToJson_drop(dict);
|
||||
return None_Json();
|
||||
}
|
||||
VecU8 key;
|
||||
int key_code = json_decoding_parse_string(rem, &key);
|
||||
if (key_code) {
|
||||
RBTree_MapVecU8ToJson_drop(dict);
|
||||
return None_Json();
|
||||
}
|
||||
SpanU8_parsing_skip_spaces(rem);
|
||||
if (!SpanU8_parsing_try_read_char(rem, ':')) {
|
||||
RBTree_MapVecU8ToJson_drop(dict);
|
||||
VecU8_drop(key);
|
||||
return None_Json();
|
||||
}
|
||||
OptionJson x = json_decoding_h(rem, depth_rem - 1);
|
||||
if (x.variant == Option_None) {
|
||||
RBTree_MapVecU8ToJson_drop(dict);
|
||||
VecU8_drop(key);
|
||||
return None_Json();
|
||||
}
|
||||
bool iret = RBTree_MapVecU8ToJson_insert(&dict, key, x.some);
|
||||
if (!iret) {
|
||||
/* Two elements of dictionary share the same key. Very illegal */
|
||||
RBTree_MapVecU8ToJson_drop(dict);
|
||||
return None_Json();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return None_Json();
|
||||
}
|
||||
|
||||
/* Given depth_allowed=w, maximum of w frames will be used on stack and the returned Json object will
|
||||
* have a maximum depth of w */
|
||||
OptionJson json_decode(SpanU8 text, U32 depth_allowed){
|
||||
OptionJson x = json_decoding_h(&text, depth_allowed);
|
||||
if (x.variant == Option_Some && text.len > 0) {
|
||||
return None_Json();
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
#endif
|
||||
@ -137,17 +137,6 @@ VecU64 marie_polygon_ear_cutting_triangulation(Spans64vec2 P){
|
||||
return triangles;
|
||||
}
|
||||
|
||||
/* Recursion is dead. Recursion remains dead. And we have killed it.
|
||||
* Used in hole-connecting triangulation algorithm */
|
||||
typedef struct {
|
||||
U64 hole_id;
|
||||
U64 vertex_in_hole_id;
|
||||
U64 progress;
|
||||
U64 progress_in_starting_vertex;
|
||||
} MarieHoleConnectTriangStackFrame;
|
||||
|
||||
#include "../../../gen/l1/eve/marie/VecMarieHoleConnectTriangStackFrame.h"
|
||||
|
||||
/* Used in hole-connecting triangulation algorithm */
|
||||
typedef struct{
|
||||
U64 hole_id;
|
||||
|
||||
6
src/l2/tests/t_parsing.c
Normal file
6
src/l2/tests/t_parsing.c
Normal file
@ -0,0 +1,6 @@
|
||||
#include "../core/json_encoded.h"
|
||||
|
||||
int main(){
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -1,3 +1,4 @@
|
||||
#include "../../l2/core/json.h"
|
||||
#include "../../l2/allie/allie.c"
|
||||
|
||||
AliceGenericMeshPath AliceGenericMeshPath_for_log(SpanU8 root_dir, U64 w, U64 r, U64 k) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user