saving bug fix
This commit is contained in:
parent
418c42a645
commit
b3b0eae267
@ -3,6 +3,7 @@
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
typedef uint8_t U8;
|
||||
typedef uint16_t U16;
|
||||
|
||||
29
src/l1/core/uint_segments.h
Normal file
29
src/l1/core/uint_segments.h
Normal 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
|
||||
@ -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>
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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 \"../../"));
|
||||
|
||||
@ -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;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user