4coder/4coder_string_match.cpp

146 lines
4.3 KiB
C++

/*
* Mr. 4th Dimention - Allen Webster
*
* 17.06.2019
*
* Routines for operating on the String_Match and String_Match_List types.
*
*/
// TOP
internal void
string_match_list_push(Arena *arena, String_Match_List *list,
Buffer_ID buffer, i32 string_id, String_Match_Flag flags, Range_i64 range){
String_Match *match = push_array(arena, String_Match, 1);
sll_queue_push(list->first, list->last, match);
list->count += 1;
match->buffer = buffer;
match->string_id = string_id;
match->flags = flags;
match->range = range;
}
internal void
string_match_list_push(Arena *arena, String_Match_List *list,
Buffer_ID buffer, i32 string_id, String_Match_Flag flags, i64 start, i64 length){
string_match_list_push(arena, list, buffer, string_id, flags,
make_range_i64(start, start + length));
}
internal String_Match_List
string_match_list_join(String_Match_List *a, String_Match_List *b){
String_Match_List list = *a;
block_zero_struct(a);
if (list.last != 0){
list.last->next = b->first;
if (b->last != 0){
list.last = b->last;
}
}
else{
list.first = b->first;
list.last = b->last;
}
list.count += b->count;
block_zero_struct(b);
return(list);
}
internal void
string_match_list_filter_flags(String_Match_List *list, String_Match_Flag must_have_flags, String_Match_Flag must_not_have_flags){
String_Match_List new_list = {};
if ((must_have_flags & must_not_have_flags) == 0){
for (String_Match *node = list->first, *next = 0;
node != 0;
node = next){
next = node->next;
if ((node->flags & must_have_flags) == must_have_flags && (node->flags & must_not_have_flags) == 0){
sll_queue_push(new_list.first, new_list.last, node);
new_list.count += 1;
}
}
}
*list = new_list;
}
internal void
string_match_list_filter_remove_buffer(String_Match_List *list, Buffer_ID buffer){
String_Match_List new_list = {};
for (String_Match *node = list->first, *next = 0;
node != 0;
node = next){
next = node->next;
if (node->buffer != buffer){
sll_queue_push(new_list.first, new_list.last, node);
new_list.count += 1;
}
}
*list = new_list;
}
internal void
string_match_list_filter_remove_buffer_predicate(Application_Links *app, String_Match_List *list, Buffer_Predicate *predicate){
String_Match_List new_list = {};
for (String_Match *node = list->first, *next = 0;
node != 0;
node = next){
next = node->next;
if (!predicate(app, node->buffer)){
sll_queue_push(new_list.first, new_list.last, node);
new_list.count += 1;
}
}
*list = new_list;
}
internal String_Match_List
string_match_list_merge_nearest(String_Match_List *a, String_Match_List *b, Range_i64 range){
String_Match_List list = {};
String_Match *node_a = a->first;
String_Match *node_b = b->first;
for (String_Match *next_a = node_a, *next_b = node_b;
node_a != 0 && node_b != 0;
node_a = next_a, node_b = next_b){
i64 dist_a = range_distance(node_a->range, range);
i64 dist_b = range_distance(node_b->range, range);
if (dist_a <= dist_b){
next_a = next_a->next;
sll_queue_push(list.first, list.last, node_a);
list.count += 1;
}
else{
next_b = next_b->next;
sll_queue_push(list.first, list.last, node_b);
list.count += 1;
}
}
Assert(node_a == 0 || node_b == 0);
// TODO(allen): this is dumb O(n) work that could be O(1)
String_Match *node = 0;
if (node_a != 0){
node = node_a;
}
else if (node_b != 0){
node = node_b;
}
for (String_Match *next = 0;
node != 0;
node = next){
next = node->next;
sll_queue_push(list.first, list.last, node);
list.count += 1;
}
block_zero_struct(a);
block_zero_struct(b);
return(list);
}
internal String_Match_List
string_match_list_merge_front_to_back(String_Match_List *a, String_Match_List *b){
return(string_match_list_merge_nearest(a, b, make_range_i64(0)));
}
// BOTTOM