saving bug fix

This commit is contained in:
Андреев Григорий 2025-10-03 11:51:19 +03:00
parent 418c42a645
commit b3b0eae267
7 changed files with 175 additions and 16 deletions

View File

@ -3,6 +3,7 @@
#include <stdint.h>
#include <stddef.h>
#include <stdbool.h>
typedef uint8_t U8;
typedef uint16_t U16;

View File

@ -0,0 +1,29 @@
#ifndef prototype1_src_l1_core_uint_segments_h
#define prototype1_src_l1_core_uint_segments_h
#include "int_primitives.h"
typedef struct {
U64 start;
U64 len;
} U64Segment;
bool U64Segment_equal_U64Segment(const U64Segment* A, const U64Segment* B){
return A->start == B->start && A->len == B->len;
}
bool U64Segment_equal_by_start(const U64Segment* A, const U64Segment* B){
return A->start == B->start;
}
bool U64Segment_less_by_start(const U64Segment* A, const U64Segment* B){
return A->start < B->start;
}
bool U64Segment_less_by_len_and_start(const U64Segment* A, const U64Segment* B){
if (A->len == B->len)
return A->start < B->start;
return A->len < B->len;
}
#endif

View File

@ -2,7 +2,6 @@
#define PROTOTYPE1_SRC_CORE_UTIL_H
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>

View File

@ -4,14 +4,28 @@
#include "../codegen/rb_tree_set_map_template_inst.h"
void generate_l1_5_template_instantiation_for_base_types(){
SpanU8 l = cstr("l1_5");
SpanU8 ns = cstr("");
SpanU8 l = cstr("l1_5"), ns = cstr("");
SpanU8 dep = cstr(
"#include \"../l1/VecAndSpan_int_primitives.h\""
);
// todo: split VecAndSpan_int_primitives into multiple files (one file per integer type)
generate_rb_tree_Set_templ_inst_guarded_header(l, ns, dep, (set_instantiation_op){.T = cstr("U64"), .t_integer = true});
generate_rb_tree_Set_templ_inst_guarded_header(l, ns, dep, (set_instantiation_op){.T = cstr("S64"), .t_integer = true});
generate_rb_tree_Set_templ_inst_guarded_header(l, ns, cstr("#include \"../../src/l1/core/uint_segments.h\""),
(set_instantiation_op){
.T = cstr("U64Segment"),
.t_primitive = true,
.alternative_equal = cstr("U64Segment_equal_by_start"),
.alternative_less = cstr("U64Segment_less_by_start"),
.alternative_comp_set_name_embed = cstr("Start")
});
generate_rb_tree_Set_templ_inst_guarded_header(l, ns, cstr("#include \"../../src/l1/core/uint_segments.h\""),
(set_instantiation_op){
.T = cstr("U64Segment"),
.t_primitive = true,
.alternative_less = cstr("U64Segment_less_by_len_and_start"),
.alternative_comp_set_name_embed = cstr("LenAndStart")
});
}
#endif

View File

@ -3,8 +3,6 @@
#include "../../l1/codegen/util_template_inst.h"
// todo: continue from here
/* We assume that T is trivially movable */
typedef struct {
SpanU8 T;
@ -12,10 +10,20 @@ typedef struct {
bool t_integer;
bool t_primitive;
bool t_clonable;
SpanU8 alternative_equal;
SpanU8 alternative_less;
SpanU8 alternative_comp_set_name_embed;
} set_instantiation_op;
void set_instantiation_op_fix(set_instantiation_op* self){
assert(self->T.len > 0);
assert(!self->t_integer || self->alternative_equal.len == 0);
assert(!self->t_integer || self->alternative_less.len == 0);
assert((self->alternative_less.len == 0 && self->alternative_equal.len
&& self->alternative_comp_set_name_embed.len
)||(
self->alternative_comp_set_name_embed.len != 0 &&
(self->alternative_less.len != 0 || self->alternative_equal.len != 0)));
if (self->t_ptr)
self->t_integer = true;
if (self->t_integer)

View File

@ -7,6 +7,8 @@
NODISCARD VecU8 codegen_rb_tree_set_key_value_NOT_EQUAL_element(set_instantiation_op op){
if (op.t_integer)
return VecU8_fmt("key != self->el.buf[cur - 1]");
if (op.alternative_equal.len != 0)
return VecU8_fmt("!%s(&key, &self->el.buf[cur - 1])", op.alternative_equal);
return VecU8_fmt("!%s_equal_%s(&key, &self->el.buf[cur - 1])", op.T, op.T);
}
@ -14,6 +16,8 @@ NODISCARD VecU8 codegen_rb_tree_set_key_value_NOT_EQUAL_element(set_instantiatio
NODISCARD VecU8 codegen_rb_tree_set_key_value_LESS_element(set_instantiation_op op){
if (op.t_integer)
return VecU8_fmt("key < self->el.buf[cur - 1]");
if (op.alternative_less.len != 0)
return VecU8_fmt("%s(&key, &self->el.buf[cur - 1])", op.alternative_less);
return VecU8_fmt("%s_less_%s(&key, &self->el.buf[cur - 1])", op.T, op.T);
}
@ -22,6 +26,8 @@ NODISCARD VecU8 codegen_rb_tree_set_key_value_LESS_element(set_instantiation_op
NODISCARD VecU8 codegen_rb_tree_set_key_ref_NOT_EQUAL_element(set_instantiation_op op){
if (op.t_integer)
return VecU8_fmt("key != self->el.buf[cur - 1]");
if (op.alternative_equal.len != 0)
return VecU8_fmt("!%s(key, &self->el.buf[cur - 1])", op.alternative_equal);
return VecU8_fmt("!%s_equal_%s(key, &self->el.buf[cur - 1])", op.T, op.T);
}
@ -29,6 +35,8 @@ NODISCARD VecU8 codegen_rb_tree_set_key_ref_NOT_EQUAL_element(set_instantiation_
NODISCARD VecU8 codegen_rb_tree_set_key_ref_EQUAL_element(set_instantiation_op op){
if (op.t_integer)
return VecU8_fmt("key == self->el.buf[cur - 1]");
if (op.alternative_equal.len != 0)
return VecU8_fmt("%s(key, &self->el.buf[cur - 1])", op.alternative_equal);
return VecU8_fmt("%s_equal_%s(ref, &self->el.buf[cur - 1])", op.T, op.T);
}
@ -36,6 +44,8 @@ NODISCARD VecU8 codegen_rb_tree_set_key_ref_EQUAL_element(set_instantiation_op o
NODISCARD VecU8 codegen_rb_tree_set_key_ref_LESS_element(set_instantiation_op op){
if (op.t_integer)
return VecU8_fmt("key < self->el.buf[cur - 1]");
if (op.alternative_less.len != 0)
return VecU8_fmt("%s(key, &self->el.buf[cur - 1])", op.alternative_less);
return VecU8_fmt("%s_less_%s(key, &self->el.buf[cur - 1])", op.T, op.T);
}
@ -86,6 +96,12 @@ NODISCARD VecU8 codegen_rb_tree_set_taking_ref_t_argument(set_instantiation_op o
return !op.t_integer ? VecU8_fmt("const %s*", op.T) : VecU8_from_span(op.T);
}
NODISCARD VecU8 get_name_of_rb_tree_set_structure(set_instantiation_op op){
if (op.alternative_comp_set_name_embed.len)
return VecU8_fmt("BuffRBTreeBy%s_Set%s", op.alternative_comp_set_name_embed, op.T);
return VecU8_fmt("BuffRBTree_Set%s", op.T);
}
/* Generates methods _insert() _pop_substitute() _erase_substitute() for SetT
* Takes ownership of strings Tc, Fc */
void codegen_append_rb_tree_set_insert_kind_method(
@ -175,7 +191,7 @@ void codegen_append_rb_tree_set_erase_kind_method(
SPACE "}\n"
"%v" /* saving_prev */
SPACE "U64 z = cur;\n"
SPACE "U64 y = (self->tree.buf[z].left == 0 || self->tree.buf[z].right == 0) ? z : RBTree_minimum_in_subtree(self->tree.buf, self->tree.buf[z].right);\n"
SPACE "U64 y = (self->tree.buf[z].left == 0 || self->tree.buf[z].right == 0) ? z : 1(self->tree.buf, self->tree.buf[z].right);\n"
SPACE "U64 x = self->tree.buf[y].left != 0 ? self->tree.buf[y].left : self->tree.buf[y].right;\n"
SPACE "assert(x != y && x != z);\n"
SPACE "U64 x_adopter = self->tree.buf[y].parent;\n"
@ -223,7 +239,7 @@ void codegen_append_rb_tree_set_erase_kind_method(
NODISCARD VecU8 generate_rb_tree_Set_template_instantiation(set_instantiation_op op){
set_instantiation_op_fix(&op);
VecU8 res = VecU8_new();
VecU8 g_set = VecU8_fmt("BuffRBTree_Set%s", op.T);
VecU8 g_set = get_name_of_rb_tree_set_structure(op);
SpanU8 set = VecU8_to_span(&g_set);
VecU8_append_vec(&res, VecU8_fmt(
"typedef struct {\n"
@ -294,7 +310,7 @@ NODISCARD VecU8 generate_rb_tree_Set_template_instantiation(set_instantiation_op
}
VecU8_append_vec(&res, VecU8_fmt(
"U64 %s_find(const %s* self, %v key) {\n" /* set, set taking_ref_t_argument */
"U64 %s_find(const %s* self, %v key) {\n" /* set, set, taking_ref_t_argument */
SPACE "U64 cur = self->root;\n"
SPACE "while (cur != 0 && %v) {\n" /* key reference not equal cur element */
SPACE SPACE "if (%v) {\n" /* key reference less than cue element */
@ -379,20 +395,111 @@ NODISCARD VecU8 generate_rb_tree_Set_template_instantiation(set_instantiation_op
SPACE "return self->root != 0 ? RBTree_maximum_in_subtree(self->tree.buf, self->root) : 0;\n"
"}\n\n", set, set));
// todo: continue from here. Implement method _pop_and_substitute()
VecU8_append_vec(&res, VecU8_fmt(
"U64 %s_find_max_less(const %s* self, %v key) {\n" /* set, set, taking_ref_t_argument */
SPACE "U64 last_less = 0;\n"
SPACE "U64 cur = self->root;\n"
SPACE "while (cur != 0) {\n"
SPACE SPACE "if (%v) {\n" /* key_ref_EQUAL_element */
SPACE SPACE SPACE "cur = cur->left;\n"
SPACE SPACE SPACE "if (cur == 0)\n"
SPACE SPACE SPACE SPACE "return last_less;\n"
SPACE SPACE SPACE "while (self->tree.buf[cur].right != 0)\n"
SPACE SPACE SPACE SPACE "cur = self->tree.buf[cur].right;\n"
SPACE SPACE SPACE "return cur;\n"
SPACE SPACE "} else if (%v) {\n" /* key_ref_LESS_element */
SPACE SPACE SPACE "cur = self->tree.buf[cur].left;\n"
SPACE SPACE "} else {\n"
SPACE SPACE SPACE "last_less = cur;\n"
SPACE SPACE SPACE "cur = self->tree.buf[cur].right;\n"
SPACE SPACE "}\n"
SPACE "}\n"
SPACE "return last_less;\n"
"}\n\n",
set, set, codegen_rb_tree_set_taking_ref_t_argument(op),
codegen_rb_tree_set_key_ref_EQUAL_element(op),
codegen_rb_tree_set_key_ref_LESS_element(op)
));
// todo: All the other methods are secondary in importance
VecU8_append_vec(&res, VecU8_fmt(
"U64 %s_find_max_less_or_eq(const %s* self, %v key) {\n" /* set, set, taking_ref_t_argument */
SPACE "U64 last_less = 0;\n"
SPACE "U64 cur = self->root;\n"
SPACE "while (cur != 0) {\n"
SPACE SPACE "if (%v) {\n" /* key_ref_EQUAL_element */
SPACE SPACE SPACE "return cur;\n"
SPACE SPACE "} else if (%v) {\n" /* key_ref_LESS_element */
SPACE SPACE SPACE "cur = self->tree.buf[cur].left;\n"
SPACE SPACE "} else {\n"
SPACE SPACE SPACE "last_less = cur;\n"
SPACE SPACE SPACE "cur = self->tree.buf[cur].right;\n"
SPACE SPACE "}\n"
SPACE "}\n"
SPACE "return last_less;\n"
"}\n\n",
set, set, codegen_rb_tree_set_taking_ref_t_argument(op),
codegen_rb_tree_set_key_ref_EQUAL_element(op),
codegen_rb_tree_set_key_ref_LESS_element(op)
));
VecU8_append_vec(&res, VecU8_fmt(
"U64 %s_find_min_grtr(const %s* self, %v key) {\n" /* set, set, taking_ref_t_argument */
SPACE "U64 last_grtr = 0;\n"
SPACE "U64 cur = self->root;\n"
SPACE "while (cur != 0) {\n"
SPACE SPACE "if (%v) {\n" /* key_ref_EQUAL_element */
SPACE SPACE SPACE "cur = cur->right;\n"
SPACE SPACE SPACE "if (cur == 0)\n"
SPACE SPACE SPACE SPACE "return last_grtr;\n"
SPACE SPACE SPACE "while (self->tree.buf[cur].left != 0)\n"
SPACE SPACE SPACE SPACE "cur = self->tree.buf[cur].left;\n"
SPACE SPACE SPACE "return cur;\n"
SPACE SPACE "} else if (%v) {\n" /* key_ref_LESS_element */
SPACE SPACE SPACE "last_grtr = cur;\n"
SPACE SPACE SPACE "cur = self->tree.buf[cur].left;\n"
SPACE SPACE "} else {\n"
SPACE SPACE SPACE "cur = self->tree.buf[cur].right;\n"
SPACE SPACE "}\n"
SPACE "}\n"
SPACE "return last_grtr;\n"
"}\n\n",
set, set, codegen_rb_tree_set_taking_ref_t_argument(op),
codegen_rb_tree_set_key_ref_EQUAL_element(op),
codegen_rb_tree_set_key_ref_LESS_element(op)
));
VecU8_append_vec(&res, VecU8_fmt(
"U64 %s_find_min_grtr_or_eq(const %s* self, %v key) {\n" /* set, set, taking_ref_t_argument */
SPACE "U64 last_grtr = 0;\n"
SPACE "U64 cur = self->root;\n"
SPACE "while (cur != 0) {\n"
SPACE SPACE "if (%v) {\n" /* key_ref_EQUAL_element */
SPACE SPACE SPACE "return cur;\n"
SPACE SPACE "} else if (%v) {\n" /* key_ref_LESS_element */
SPACE SPACE SPACE "last_grtr = cur;\n"
SPACE SPACE SPACE "cur = self->tree.buf[cur].left;\n"
SPACE SPACE "} else {\n"
SPACE SPACE SPACE "cur = self->tree.buf[cur].right;\n"
SPACE SPACE "}\n"
SPACE "}\n"
SPACE "return last_grtr;\n"
"}\n\n",
set, set, codegen_rb_tree_set_taking_ref_t_argument(op),
codegen_rb_tree_set_key_ref_EQUAL_element(op),
codegen_rb_tree_set_key_ref_LESS_element(op)
));
VecU8_drop(g_set);
return res;
}
void generate_rb_tree_Set_templ_inst_eve_header(SpanU8 layer, SpanU8 bonus_ns, option_template_instantiation_op op) {
void generate_rb_tree_Set_templ_inst_eve_header(SpanU8 layer, SpanU8 bonus_ns, set_instantiation_op op) {
VecU8 text = VecU8_from_cstr("/* Automatically generated file. Do not edit it.\n"
" * Do not include it in more than one place */\n\n");
VecU8_append_vec(&text, generate_OptionT_struct_and_methods(op));
VecU8 nt_path = VecU8_fmt("%s/eve/%s/BuffRBTree_Set%s%c", layer, bonus_ns, op.T, 0);
VecU8_append_vec(&text, generate_rb_tree_Set_template_instantiation(op));
VecU8 nt_path = VecU8_fmt("%s/eve/%s/%s.h%c", layer, bonus_ns, op.T, get_name_of_rb_tree_set_structure(op));
write_whole_file_or_abort((const char*)nt_path.buf, VecU8_to_span(&text));
VecU8_drop(nt_path);
VecU8_drop(text);
@ -402,7 +509,8 @@ void generate_rb_tree_Set_templ_inst_guarded_header(
SpanU8 layer, SpanU8 bonus_ns, SpanU8 dependencies, set_instantiation_op op
){
assert(layer.len > 1);
VecU8 path = VecU8_fmt("%s/%s%sBuffRBTree_Set%s.h", layer, bonus_ns, bonus_ns.len ? cstr("/") : cstr(""), op.T);
VecU8 path = VecU8_fmt("%s/%s%s%v.h", layer, bonus_ns, bonus_ns.len ? cstr("/") : cstr(""),
get_name_of_rb_tree_set_structure(op));
GeneratedHeader head = begin_header(VecU8_to_span(&path));
VecU8_drop(path);
VecU8_append_span(&head.result, cstr("#include \"../../"));

View File

@ -121,7 +121,7 @@ void RBTree_steal_neighbours(RBTreeNode* tree, U64* root, U64 fr, U64 to){
/* helper function (used in _erase, _find_min methods). It is assumed that s is not null.
* Guaranteed to return no-null
*/
U64 RBTree_minimum_in_subtree(RBTreeNode* tree, U64 s){
U64 RBTree_minimum_in_subtree(const RBTreeNode* tree, U64 s){
assert(s != 0);
while (tree[s].left != 0)
s = tree[s].left;
@ -131,7 +131,7 @@ U64 RBTree_minimum_in_subtree(RBTreeNode* tree, U64 s){
/* helper function (used in _find_max, _find_prev methods). It is assumed that s is not null.
* Guaranteed to return no-null
*/
U64 RBTree_maximum_in_subtree(RBTreeNode* tree, U64 s){
U64 RBTree_maximum_in_subtree(const RBTreeNode* tree, U64 s){
assert(s != 0);
while (tree[s].right != 0)
s = tree[s].right;