Basics of relex are now in place
This commit is contained in:
parent
7c495a160d
commit
4640349de8
|
@ -548,9 +548,6 @@ TYPEDEF_FUNC i32 File_Edit_Range_Function(struct Application_Links *app, Buffer_
|
|||
Interval_i64 range, String_Const_u8 text);
|
||||
#define FILE_EDIT_RANGE_SIG(name) i32 name(struct Application_Links *app, Buffer_ID buffer_id, Interval_i64 range, String_Const_u8 text)
|
||||
|
||||
TYPEDEF_FUNC i32 File_Edit_Finished_Function(struct Application_Links *app, Buffer_ID *buffer_ids, i32 buffer_id_count);
|
||||
#define FILE_EDIT_FINISHED_SIG(name) i32 name(struct Application_Links *app, Buffer_ID *buffer_ids, i32 buffer_id_count)
|
||||
|
||||
TYPEDEF_FUNC i32 File_Externally_Modified_Function(struct Application_Links *app, Buffer_ID buffer_id);
|
||||
#define FILE_EXTERNALLY_MODIFIED_SIG(name) i32 name(struct Application_Links *app, Buffer_ID buffer_id)
|
||||
|
||||
|
|
|
@ -291,6 +291,17 @@ block_fill_u64(void *a, umem size, u64 val){
|
|||
#define block_match_struct(a,b) block_match((a), (b), sizeof(*(a)))
|
||||
#define block_match_array(a,b) block_match((a), (b), sizeof(a))
|
||||
|
||||
internal void
|
||||
block_copy_array_shift__inner(void *dst, void *src, umem it_size, Interval_i64 range, i64 shift){
|
||||
u8 *dptr = (u8*)dst;
|
||||
u8 *sptr = (u8*)src;
|
||||
dptr += it_size*(range.first + shift);
|
||||
sptr += it_size*range.first;
|
||||
block_copy(dptr, sptr, it_size*(range.one_past_last - range.first));
|
||||
}
|
||||
|
||||
#define block_copy_array_shift(d,s,r,h) block_copy_array_shift__inner((d),(s),sizeof(*(d)),(r),(h))
|
||||
|
||||
////////////////////////////////
|
||||
|
||||
internal f32
|
||||
|
|
|
@ -1027,6 +1027,24 @@ BUFFER_NAME_RESOLVER_SIG(default_buffer_name_resolution){
|
|||
}
|
||||
}
|
||||
|
||||
internal void
|
||||
do_full_lex(Application_Links *app, Buffer_ID buffer_id){
|
||||
Scratch_Block scratch(app);
|
||||
String_Const_u8 contents = push_whole_buffer(app, scratch, buffer_id);
|
||||
Token_List list = lex_full_input_cpp(scratch, contents);
|
||||
|
||||
Managed_Scope scope = buffer_get_managed_scope(app, buffer_id);
|
||||
Base_Allocator *allocator = managed_scope_allocator(app, scope);
|
||||
Token_Array tokens = {};
|
||||
tokens.tokens = base_array(allocator, Token, list.total_count);
|
||||
tokens.count = list.total_count;
|
||||
tokens.max = list.total_count;
|
||||
token_fill_memory_from_list(tokens.tokens, &list);
|
||||
|
||||
Token_Array *tokens_ptr = scope_attachment(app, scope, attachment_tokens, Token_Array);
|
||||
block_copy_struct(tokens_ptr, &tokens);
|
||||
}
|
||||
|
||||
BUFFER_HOOK_SIG(default_file_settings){
|
||||
b32 treat_as_code = false;
|
||||
b32 lex_without_strings = false;
|
||||
|
@ -1144,18 +1162,7 @@ BUFFER_HOOK_SIG(default_file_settings){
|
|||
}
|
||||
|
||||
if (use_lexer){
|
||||
Temp_Memory temp = begin_temp(scratch);
|
||||
String_Const_u8 contents = push_whole_buffer(app, scratch, buffer_id);
|
||||
Managed_Scope scope = buffer_get_managed_scope(app, buffer_id);
|
||||
Base_Allocator *allocator = managed_scope_allocator(app, scope);
|
||||
Arena alloc_arena = make_arena(allocator);
|
||||
Token_List list = lex_full_input_cpp(&alloc_arena, contents);
|
||||
Token_Array tokens = token_array_from_list(&alloc_arena, &list);
|
||||
|
||||
Token_Array *tokens_ptr = scope_attachment(app, scope, attachment_tokens, Token_Array);
|
||||
block_copy_struct(tokens_ptr, &tokens);
|
||||
|
||||
end_temp(temp);
|
||||
do_full_lex(app, buffer_id);
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
@ -1176,8 +1183,8 @@ BUFFER_HOOK_SIG(default_file_settings){
|
|||
}
|
||||
|
||||
BUFFER_HOOK_SIG(default_new_file){
|
||||
// no meaning for return
|
||||
// buffer_id
|
||||
// no meaning for return
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
@ -1186,7 +1193,7 @@ BUFFER_HOOK_SIG(default_file_save){
|
|||
if (global_config.automatically_indent_text_on_save &&
|
||||
buffer_get_setting(app, buffer_id, BufferSetting_VirtualWhitespace, &is_virtual)){
|
||||
if (is_virtual){
|
||||
i32 buffer_size = (i32)buffer_get_size(app, buffer_id);
|
||||
i64 buffer_size = buffer_get_size(app, buffer_id);
|
||||
buffer_auto_indent(app, buffer_id, 0, buffer_size, DEF_TAB_WIDTH, DEFAULT_INDENT_FLAGS | AutoIndent_FullTokens);
|
||||
}
|
||||
}
|
||||
|
@ -1195,23 +1202,73 @@ BUFFER_HOOK_SIG(default_file_save){
|
|||
}
|
||||
|
||||
FILE_EDIT_RANGE_SIG(default_file_edit_range){
|
||||
// no meaning for return
|
||||
// buffer_id, range, text
|
||||
return(0);
|
||||
}
|
||||
|
||||
FILE_EDIT_FINISHED_SIG(default_file_edit_finished){
|
||||
#if 0
|
||||
for (i32 i = 0; i < buffer_id_count; i += 1){
|
||||
// buffer_ids[i]
|
||||
|
||||
Interval_i64 replace_range = Ii64(range.first, range.first + text.size);
|
||||
i64 insert_size = range_size(range);
|
||||
i64 text_shift = replace_range_shift(replace_range, insert_size);
|
||||
|
||||
Scratch_Block scratch(app);
|
||||
|
||||
Managed_Scope scope = buffer_get_managed_scope(app, buffer_id);
|
||||
Token_Array *ptr = scope_attachment(app, scope, attachment_tokens, Token_Array);
|
||||
if (ptr != 0 && ptr->tokens != 0){
|
||||
i64 token_index_first = token_relex_first(ptr, range.first, 1);
|
||||
i64 token_index_resync_guess = token_relex_resync(ptr, range.one_past_last, 16);
|
||||
|
||||
Token *token_first = ptr->tokens + token_index_first;
|
||||
Token *token_resync = ptr->tokens + token_index_resync_guess;
|
||||
|
||||
Interval_i64 relex_range = Ii64(token_first->pos, token_resync->pos + token_resync->size);
|
||||
String_Const_u8 partial_text = push_buffer_range(app, scratch, buffer_id, relex_range);
|
||||
|
||||
Token_List relex_list = lex_full_input_cpp(scratch, partial_text);
|
||||
if (relex_range.one_past_last < buffer_get_size(app, buffer_id)){
|
||||
token_drop_eof(&relex_list);
|
||||
}
|
||||
|
||||
Token_Relex relex = token_relex(relex_list, token_first->pos - text_shift,
|
||||
ptr->tokens, token_index_first, token_index_resync_guess);
|
||||
|
||||
Base_Allocator *allocator = managed_scope_allocator(app, scope);
|
||||
|
||||
if (relex.successful_resync){
|
||||
i64 token_index_resync = relex.first_resync_index;
|
||||
|
||||
Interval_i64 head = Ii64(0, token_index_first);
|
||||
Interval_i64 tail = Ii64(token_index_resync, ptr->count);
|
||||
i64 tail_shift = relex_list.total_count - (token_index_resync - token_index_first);
|
||||
|
||||
i64 new_tokens_count = ptr->count + tail_shift;
|
||||
Token *new_tokens = base_array(allocator, Token, new_tokens_count);
|
||||
|
||||
Token *old_tokens = ptr->tokens;
|
||||
block_copy_array_shift(new_tokens, old_tokens, head, 0);
|
||||
for (i64 i = tail.first; i < tail.one_past_last; i += 1){
|
||||
old_tokens[i].pos += text_shift;
|
||||
}
|
||||
block_copy_array_shift(new_tokens, ptr->tokens, tail, tail_shift);
|
||||
token_fill_memory_from_list(new_tokens + head.one_past_last, &relex_list);
|
||||
|
||||
base_free(allocator, ptr->tokens);
|
||||
|
||||
ptr->tokens = new_tokens;
|
||||
ptr->count = new_tokens_count;
|
||||
ptr->max = new_tokens_count;
|
||||
}
|
||||
else{
|
||||
scratch.restore();
|
||||
base_free(allocator, ptr->tokens);
|
||||
do_full_lex(app, buffer_id);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// no meaning for return
|
||||
return(0);
|
||||
}
|
||||
|
||||
FILE_EXTERNALLY_MODIFIED_SIG(default_file_externally_modified){
|
||||
// buffer_id
|
||||
Scratch_Block scratch(app);
|
||||
String_Const_u8 name = push_buffer_unique_name(app, scratch, buffer_id);
|
||||
String_Const_u8 str = push_u8_stringf(scratch, "Modified externally: %s\n", name.str);
|
||||
|
@ -1331,7 +1388,6 @@ set_all_default_hooks(Bind_Helper *context){
|
|||
set_new_file_hook(context, default_new_file);
|
||||
set_save_file_hook(context, default_file_save);
|
||||
set_file_edit_range_hook(context, default_file_edit_range);
|
||||
set_file_edit_finished_hook(context, default_file_edit_finished);
|
||||
set_file_externally_modified_hook(context, default_file_externally_modified);
|
||||
|
||||
set_end_file_hook(context, end_file_close_jump_list);
|
||||
|
|
|
@ -196,12 +196,14 @@ get_bindings(void *data, i32 size){
|
|||
set_open_file_hook(context, default_file_settings);
|
||||
set_new_file_hook(context, default_new_file);
|
||||
set_save_file_hook(context, default_file_save);
|
||||
set_file_edit_range_hook(context, default_file_edit_range);
|
||||
set_file_externally_modified_hook(context, default_file_externally_modified);
|
||||
|
||||
set_end_file_hook(context, end_file_close_jump_list);
|
||||
|
||||
set_input_filter(context, default_suppress_mouse_filter);
|
||||
set_command_caller(context, default_command_caller);
|
||||
set_render_caller(context, default_render_caller);
|
||||
|
||||
set_input_filter(context, default_suppress_mouse_filter);
|
||||
set_scroll_rule(context, smooth_scroll_rule);
|
||||
set_buffer_name_resolver(context, default_buffer_name_resolution);
|
||||
set_modify_color_table_hook(context, default_modify_color_table);
|
||||
|
|
|
@ -219,15 +219,6 @@ set_file_edit_range_hook(Bind_Helper *helper, File_Edit_Range_Function *func){
|
|||
write_unit(helper, unit);
|
||||
}
|
||||
|
||||
internal void
|
||||
set_file_edit_finished_hook(Bind_Helper *helper, File_Edit_Finished_Function *func){
|
||||
Binding_Unit unit = {};
|
||||
unit.type = unit_hook;
|
||||
unit.hook.hook_id = special_hook_file_edit_finished;
|
||||
unit.hook.func = (void*)func;
|
||||
write_unit(helper, unit);
|
||||
}
|
||||
|
||||
internal void
|
||||
set_file_externally_modified_hook(Bind_Helper *helper, File_Externally_Modified_Function *func){
|
||||
Binding_Unit unit = {};
|
||||
|
|
150
4coder_table.cpp
150
4coder_table.cpp
|
@ -134,22 +134,24 @@ table_rehash(Table_u64_u64 *dst, Table_u64_u64 *src){
|
|||
internal b32
|
||||
table_insert(Table_u64_u64 *table, u64 key, u64 val){
|
||||
b32 result = false;
|
||||
Table_Lookup lookup = table_lookup(table, key);
|
||||
if (!lookup.found_match){
|
||||
if ((table->dirty_count + 1)*8 >= table->slot_count*7){
|
||||
i32 new_slot_count = table->slot_count;
|
||||
if (table->used_count*2 >= table->slot_count){
|
||||
new_slot_count = table->slot_count*4;
|
||||
if (key != table_empty_key && key != table_erased_key){
|
||||
Table_Lookup lookup = table_lookup(table, key);
|
||||
if (!lookup.found_match){
|
||||
if ((table->dirty_count + 1)*8 >= table->slot_count*7){
|
||||
i32 new_slot_count = table->slot_count;
|
||||
if (table->used_count*2 >= table->slot_count){
|
||||
new_slot_count = table->slot_count*4;
|
||||
}
|
||||
Table_u64_u64 new_table = make_table_u64_u64(table->allocator, new_slot_count);
|
||||
table_rehash(&new_table, table);
|
||||
table_free(table);
|
||||
*table = new_table;
|
||||
lookup = table_lookup(table, key);
|
||||
Assert(lookup.found_empty_slot);
|
||||
}
|
||||
Table_u64_u64 new_table = make_table_u64_u64(table->allocator, new_slot_count);
|
||||
table_rehash(&new_table, table);
|
||||
table_free(table);
|
||||
*table = new_table;
|
||||
lookup = table_lookup(table, key);
|
||||
Assert(lookup.found_empty_slot);
|
||||
table_insert__inner(table, lookup, val);
|
||||
result = true;
|
||||
}
|
||||
table_insert__inner(table, lookup, val);
|
||||
result = true;
|
||||
}
|
||||
return(result);
|
||||
}
|
||||
|
@ -288,22 +290,24 @@ table_rehash(Table_u32_u16 *dst, Table_u32_u16 *src){
|
|||
internal b32
|
||||
table_insert(Table_u32_u16 *table, u32 key, u16 val){
|
||||
b32 result = false;
|
||||
Table_Lookup lookup = table_lookup(table, key);
|
||||
if (!lookup.found_match){
|
||||
if ((table->dirty_count + 1)*8 >= table->slot_count*7){
|
||||
i32 new_slot_count = table->slot_count;
|
||||
if (table->used_count*2 >= table->slot_count){
|
||||
new_slot_count = table->slot_count*4;
|
||||
if (key != table_empty_u32_key && key != table_erased_u32_key){
|
||||
Table_Lookup lookup = table_lookup(table, key);
|
||||
if (!lookup.found_match){
|
||||
if ((table->dirty_count + 1)*8 >= table->slot_count*7){
|
||||
i32 new_slot_count = table->slot_count;
|
||||
if (table->used_count*2 >= table->slot_count){
|
||||
new_slot_count = table->slot_count*4;
|
||||
}
|
||||
Table_u32_u16 new_table = make_table_u32_u16(table->allocator, new_slot_count);
|
||||
table_rehash(&new_table, table);
|
||||
table_free(table);
|
||||
*table = new_table;
|
||||
lookup = table_lookup(table, key);
|
||||
Assert(lookup.found_empty_slot);
|
||||
}
|
||||
Table_u32_u16 new_table = make_table_u32_u16(table->allocator, new_slot_count);
|
||||
table_rehash(&new_table, table);
|
||||
table_free(table);
|
||||
*table = new_table;
|
||||
lookup = table_lookup(table, key);
|
||||
Assert(lookup.found_empty_slot);
|
||||
table_insert__inner(table, lookup, key, val);
|
||||
result = true;
|
||||
}
|
||||
table_insert__inner(table, lookup, key, val);
|
||||
result = true;
|
||||
}
|
||||
return(result);
|
||||
}
|
||||
|
@ -453,22 +457,24 @@ table_rehash(Table_Data_u64 *dst, Table_Data_u64 *src){
|
|||
internal b32
|
||||
table_insert(Table_Data_u64 *table, Data key, u64 val){
|
||||
b32 result = false;
|
||||
Table_Lookup lookup = table_lookup(table, key);
|
||||
if (!lookup.found_match){
|
||||
if ((table->dirty_count + 1)*8 >= table->slot_count*7){
|
||||
i32 new_slot_count = table->slot_count;
|
||||
if (table->used_count*2 >= table->slot_count){
|
||||
new_slot_count = table->slot_count*4;
|
||||
if (key.data != 0){
|
||||
Table_Lookup lookup = table_lookup(table, key);
|
||||
if (!lookup.found_match){
|
||||
if ((table->dirty_count + 1)*8 >= table->slot_count*7){
|
||||
i32 new_slot_count = table->slot_count;
|
||||
if (table->used_count*2 >= table->slot_count){
|
||||
new_slot_count = table->slot_count*4;
|
||||
}
|
||||
Table_Data_u64 new_table = make_table_Data_u64(table->allocator, new_slot_count);
|
||||
table_rehash(&new_table, table);
|
||||
table_free(table);
|
||||
*table = new_table;
|
||||
lookup = table_lookup(table, key);
|
||||
Assert(lookup.found_empty_slot);
|
||||
}
|
||||
Table_Data_u64 new_table = make_table_Data_u64(table->allocator, new_slot_count);
|
||||
table_rehash(&new_table, table);
|
||||
table_free(table);
|
||||
*table = new_table;
|
||||
lookup = table_lookup(table, key);
|
||||
Assert(lookup.found_empty_slot);
|
||||
table_insert__inner(table, lookup, key, val);
|
||||
result = true;
|
||||
}
|
||||
table_insert__inner(table, lookup, key, val);
|
||||
result = true;
|
||||
}
|
||||
return(result);
|
||||
}
|
||||
|
@ -612,22 +618,24 @@ table_rehash(Table_u64_Data *dst, Table_u64_Data *src){
|
|||
internal b32
|
||||
table_insert(Table_u64_Data *table, u64 key, Data val){
|
||||
b32 result = false;
|
||||
Table_Lookup lookup = table_lookup(table, key);
|
||||
if (!lookup.found_match){
|
||||
if ((table->dirty_count + 1)*8 >= table->slot_count*7){
|
||||
i32 new_slot_count = table->slot_count;
|
||||
if (table->used_count*2 >= table->slot_count){
|
||||
new_slot_count = table->slot_count*4;
|
||||
if (key != table_empty_key && table_erased_key){
|
||||
Table_Lookup lookup = table_lookup(table, key);
|
||||
if (!lookup.found_match){
|
||||
if ((table->dirty_count + 1)*8 >= table->slot_count*7){
|
||||
i32 new_slot_count = table->slot_count;
|
||||
if (table->used_count*2 >= table->slot_count){
|
||||
new_slot_count = table->slot_count*4;
|
||||
}
|
||||
Table_u64_Data new_table = make_table_u64_Data(table->allocator, new_slot_count);
|
||||
table_rehash(&new_table, table);
|
||||
table_free(table);
|
||||
*table = new_table;
|
||||
lookup = table_lookup(table, key);
|
||||
Assert(lookup.found_empty_slot);
|
||||
}
|
||||
Table_u64_Data new_table = make_table_u64_Data(table->allocator, new_slot_count);
|
||||
table_rehash(&new_table, table);
|
||||
table_free(table);
|
||||
*table = new_table;
|
||||
lookup = table_lookup(table, key);
|
||||
Assert(lookup.found_empty_slot);
|
||||
table_insert__inner(table, lookup, val);
|
||||
result = true;
|
||||
}
|
||||
table_insert__inner(table, lookup, val);
|
||||
result = true;
|
||||
}
|
||||
return(result);
|
||||
}
|
||||
|
@ -772,22 +780,24 @@ table_rehash(Table_Data_Data *dst, Table_Data_Data *src){
|
|||
internal b32
|
||||
table_insert(Table_Data_Data *table, Data key, Data val){
|
||||
b32 result = false;
|
||||
Table_Lookup lookup = table_lookup(table, key);
|
||||
if (!lookup.found_match){
|
||||
if ((table->dirty_count + 1)*8 >= table->slot_count*7){
|
||||
i32 new_slot_count = table->slot_count;
|
||||
if (table->used_count*2 >= table->slot_count){
|
||||
new_slot_count = table->slot_count*4;
|
||||
if (key.data != 0){
|
||||
Table_Lookup lookup = table_lookup(table, key);
|
||||
if (!lookup.found_match){
|
||||
if ((table->dirty_count + 1)*8 >= table->slot_count*7){
|
||||
i32 new_slot_count = table->slot_count;
|
||||
if (table->used_count*2 >= table->slot_count){
|
||||
new_slot_count = table->slot_count*4;
|
||||
}
|
||||
Table_Data_Data new_table = make_table_Data_Data(table->allocator, new_slot_count);
|
||||
table_rehash(&new_table, table);
|
||||
table_free(table);
|
||||
*table = new_table;
|
||||
lookup = table_lookup(table, key);
|
||||
Assert(lookup.found_empty_slot);
|
||||
}
|
||||
Table_Data_Data new_table = make_table_Data_Data(table->allocator, new_slot_count);
|
||||
table_rehash(&new_table, table);
|
||||
table_free(table);
|
||||
*table = new_table;
|
||||
lookup = table_lookup(table, key);
|
||||
Assert(lookup.found_empty_slot);
|
||||
table_insert__inner(table, lookup, key, val);
|
||||
result = true;
|
||||
}
|
||||
table_insert__inner(table, lookup, key, val);
|
||||
result = true;
|
||||
}
|
||||
return(result);
|
||||
}
|
||||
|
|
167
4coder_token.cpp
167
4coder_token.cpp
|
@ -23,18 +23,35 @@ token_list_push(Arena *arena, Token_List *list, Token *token){
|
|||
list->total_count += 1;
|
||||
}
|
||||
|
||||
internal void
|
||||
token_fill_memory_from_list(Token *dst, Token_List *list){
|
||||
Token *ptr = dst;
|
||||
for (Token_Block *node = list->first;
|
||||
node != 0;
|
||||
node = node->next){
|
||||
block_copy_dynamic_array(ptr, node->tokens, node->count);
|
||||
ptr += node->count;
|
||||
}
|
||||
}
|
||||
|
||||
internal Token_Array
|
||||
token_array_from_list_always_copy(Arena *arena, Token_List *list){
|
||||
Token_Array array = {};
|
||||
if (list->node_count >= 1){
|
||||
array.tokens = push_array(arena, Token, list->total_count);
|
||||
token_fill_memory_from_list(array.tokens, list);
|
||||
array.count = list->total_count;
|
||||
array.max = array.count;
|
||||
}
|
||||
return(array);
|
||||
}
|
||||
|
||||
internal Token_Array
|
||||
token_array_from_list(Arena *arena, Token_List *list){
|
||||
Token_Array array = {};
|
||||
if (list->node_count > 1){
|
||||
array.tokens = push_array(arena, Token, list->total_count);
|
||||
Token *ptr = array.tokens;
|
||||
for (Token_Block *node = list->first;
|
||||
node != 0;
|
||||
node = node->next){
|
||||
block_copy_dynamic_array(ptr, node->tokens, node->count);
|
||||
ptr += node->count;
|
||||
}
|
||||
token_fill_memory_from_list(array.tokens, list);
|
||||
array.count = list->total_count;
|
||||
array.max = array.count;
|
||||
}
|
||||
|
@ -49,27 +66,29 @@ token_array_from_list(Arena *arena, Token_List *list){
|
|||
internal i64
|
||||
token_index_from_pos(Token *tokens, i64 count, i64 pos){
|
||||
i64 result = 0;
|
||||
if (pos >= tokens[count - 1].pos){
|
||||
result = count - 1;
|
||||
}
|
||||
else if (pos < 0){
|
||||
result = 0;
|
||||
}
|
||||
else{
|
||||
i64 first = 0;
|
||||
i64 one_past_last = count;
|
||||
for (;;){
|
||||
i64 index = (first + one_past_last) >> 1;
|
||||
i64 index_pos = tokens[index].pos;
|
||||
if (index_pos > pos){
|
||||
one_past_last = index;
|
||||
}
|
||||
else if (index_pos + tokens[index].size <= pos){
|
||||
first = index + 1;
|
||||
}
|
||||
else{
|
||||
result = index;
|
||||
break;
|
||||
if (count > 0){
|
||||
if (pos >= tokens[count - 1].pos){
|
||||
result = count - 1;
|
||||
}
|
||||
else if (pos <= tokens[0].pos){
|
||||
result = 0;
|
||||
}
|
||||
else{
|
||||
i64 first = 0;
|
||||
i64 one_past_last = count;
|
||||
for (;;){
|
||||
i64 index = (first + one_past_last) >> 1;
|
||||
i64 index_pos = tokens[index].pos;
|
||||
if (index_pos > p){
|
||||
one_past_last = index;
|
||||
}
|
||||
else if (index_pos + tokens[index].size <= pos){
|
||||
first = index + 1;
|
||||
}
|
||||
else{
|
||||
result = index;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -562,5 +581,97 @@ token_it_dec(Token_Iterator *it){
|
|||
return(0);
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
|
||||
internal void
|
||||
token_drop_eof(Token_List *list){
|
||||
if (list->last != 0){
|
||||
Token_Block *block = list->last;
|
||||
if (block->tokens[block->count - 1].kind == TokenBaseKind_EOF){
|
||||
list->total_count -= 1;
|
||||
block->count -= 1;
|
||||
if (block->count == 0){
|
||||
zdll_remove(list->first, list->last, block);
|
||||
list->node_count -= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
|
||||
internal i64
|
||||
token_relex_first(Token_Array *tokens, i64 edit_range_first, i64 backup_repeats){
|
||||
Token_Iterator_Array it = token_iterator_pos(0, tokens, edit_range_first);
|
||||
b32 good_status = true;
|
||||
for (i64 i = 0; i < backup_repeats && good_status; i += 1){
|
||||
good_status = token_it_dec(&it);
|
||||
}
|
||||
if (good_status){
|
||||
for (;;){
|
||||
Token *token = token_it_read(&it);
|
||||
if (!HasFlag(token->flags, TokenBaseFlag_PreprocessorBody)){
|
||||
break;
|
||||
}
|
||||
if (!token_it_dec(&it)){
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return(token_it_index(&it));
|
||||
}
|
||||
|
||||
internal i64
|
||||
token_relex_resync(Token_Array *tokens, i64 edit_range_first, i64 look_ahead_repeats){
|
||||
Token_Iterator_Array it = token_iterator_pos(0, tokens, edit_range_first);
|
||||
b32 good_status = true;
|
||||
for (i64 i = 0; i < look_ahead_repeats && good_status; i += 1){
|
||||
good_status = token_it_inc(&it);
|
||||
}
|
||||
if (good_status){
|
||||
for (;;){
|
||||
Token *token = token_it_read(&it);
|
||||
if (!HasFlag(token->flags, TokenBaseFlag_PreprocessorBody)){
|
||||
break;
|
||||
}
|
||||
if (!token_it_inc(&it)){
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return(token_it_index(&it));
|
||||
}
|
||||
|
||||
internal Token_Relex
|
||||
token_relex(Token_List relex_list, i64 new_pos_to_old_pos_shift, Token *tokens, i64 relex_first, i64 relex_last){
|
||||
Token_Relex relex = {};
|
||||
if (relex_list.total_count > 0){
|
||||
Token_Array relexed_tokens = {tokens + relex_first, relex_last - relex_first + 1};
|
||||
Token_Iterator_List it = token_iterator_index(0, &relex_list, relex_list.total_count - 1);
|
||||
for (;;){
|
||||
Token *token = token_it_read(&it);
|
||||
i64 new_pos_rebased = token->pos + new_pos_to_old_pos_shift;
|
||||
i64 old_token_index = token_index_from_pos(&relexed_tokens, new_pos_rebased);
|
||||
Token *old_token = relexed_tokens.tokens + old_token_index;
|
||||
if (new_pos_rebased == old_token->pos &&
|
||||
token->size == old_token->size &&
|
||||
token->kind == old_token->kind &&
|
||||
token->sub_kind == old_token->sub_kind &&
|
||||
token->flags == old_token->flags &&
|
||||
token->sub_flags == old_token->sub_flags){
|
||||
relex.successful_resync = true;
|
||||
relex.first_resync_index = relex_first + old_token_index;
|
||||
}
|
||||
else{
|
||||
break;
|
||||
}
|
||||
if (!token_it_dec_all(&it)){
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return(relex);
|
||||
}
|
||||
|
||||
// BOTTOM
|
||||
|
||||
|
|
|
@ -81,6 +81,11 @@ struct Token_List{
|
|||
i64 total_count;
|
||||
};
|
||||
|
||||
struct Token_Relex{
|
||||
b32 successful_resync;
|
||||
i64 first_resync_index;
|
||||
};
|
||||
|
||||
struct Token_Iterator_Array{
|
||||
u64 user_id;
|
||||
Token *ptr;
|
||||
|
|
68
4ed.cpp
68
4ed.cpp
|
@ -173,7 +173,6 @@ interpret_binding_buffer(Models *models, void *buffer, i32 size){
|
|||
models->hook_save_file = 0;
|
||||
models->hook_end_file = 0;
|
||||
models->hook_file_edit_range = 0;
|
||||
models->hook_file_edit_finished = 0;
|
||||
models->command_caller = 0;
|
||||
models->render_caller = 0;
|
||||
models->input_filter = 0;
|
||||
|
@ -379,11 +378,6 @@ interpret_binding_buffer(Models *models, void *buffer, i32 size){
|
|||
models->hook_file_edit_range = (File_Edit_Range_Function*)unit->hook.func;
|
||||
}break;
|
||||
|
||||
case special_hook_file_edit_finished:
|
||||
{
|
||||
models->hook_file_edit_finished = (File_Edit_Finished_Function*)unit->hook.func;
|
||||
}break;
|
||||
|
||||
case special_hook_file_externally_modified:
|
||||
{
|
||||
models->hook_file_externally_modified = (File_Externally_Modified_Function*)unit->hook.func;
|
||||
|
@ -1346,68 +1340,6 @@ App_Step_Sig(app_step){
|
|||
}
|
||||
}
|
||||
|
||||
// NOTE(allen): hook for files marked "edit finished"
|
||||
{
|
||||
File_Edit_Finished_Function *hook_file_edit_finished = models->hook_file_edit_finished;
|
||||
if (hook_file_edit_finished != 0){
|
||||
Working_Set *working_set = &models->working_set;
|
||||
if (working_set->edit_finished_count > 0){
|
||||
Assert(working_set->edit_finished_sentinel.next != 0);
|
||||
b32 trigger_hook = false;
|
||||
|
||||
u32 elapse_time = models->edit_finished_hook_repeat_speed;
|
||||
if (elapse_time != 0){
|
||||
trigger_hook = true;
|
||||
}
|
||||
else if (working_set->time_of_next_edit_finished_signal == 0){
|
||||
u32 trigger_window_length = 0;
|
||||
if (elapse_time > 5){
|
||||
trigger_window_length = elapse_time - 5;
|
||||
}
|
||||
u64 trigger_time = system->now_time() + (u64)trigger_window_length*1000LLU;
|
||||
working_set->time_of_next_edit_finished_signal = trigger_time;
|
||||
system->wake_up_timer_set(working_set->edit_finished_timer, elapse_time);
|
||||
}
|
||||
else if (system->now_time() >= working_set->time_of_next_edit_finished_signal){
|
||||
trigger_hook = true;
|
||||
}
|
||||
if (trigger_hook){
|
||||
Arena *scratch = &models->mem.arena;
|
||||
Temp_Memory temp = begin_temp(scratch);
|
||||
Node *first = working_set->edit_finished_sentinel.next;
|
||||
Node *one_past_last = &working_set->edit_finished_sentinel;
|
||||
|
||||
i32 max_id_count = working_set->edit_finished_count;
|
||||
Editing_File **file_ptrs = push_array(scratch, Editing_File*, max_id_count);
|
||||
Buffer_ID *ids = push_array(scratch, Buffer_ID, max_id_count);
|
||||
i32 id_count = 0;
|
||||
for (Node *node = first;
|
||||
node != one_past_last;
|
||||
node = node->next){
|
||||
Editing_File *file_ptr = CastFromMember(Editing_File, edit_finished_mark_node, node);
|
||||
file_ptrs[id_count] = file_ptr;
|
||||
ids[id_count] = file_ptr->id;
|
||||
id_count += 1;
|
||||
}
|
||||
|
||||
working_set->do_not_mark_edits = true;
|
||||
hook_file_edit_finished(&models->app_links, ids, id_count);
|
||||
working_set->do_not_mark_edits = false;
|
||||
|
||||
for (i32 i = 0; i < id_count; i += 1){
|
||||
file_ptrs[i]->edit_finished_marked = false;
|
||||
}
|
||||
|
||||
dll_init_sentinel(&working_set->edit_finished_sentinel);
|
||||
working_set->edit_finished_count = 0;
|
||||
working_set->time_of_next_edit_finished_signal = 0;
|
||||
|
||||
end_temp(temp);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE(allen): if the exit signal has been sent, run the exit hook.
|
||||
if (input->trying_to_kill){
|
||||
models->keep_playing = false;
|
||||
|
|
|
@ -63,7 +63,6 @@ struct Models{
|
|||
Buffer_Hook_Function *hook_save_file;
|
||||
Buffer_Hook_Function *hook_end_file;
|
||||
File_Edit_Range_Function *hook_file_edit_range;
|
||||
File_Edit_Finished_Function *hook_file_edit_finished;
|
||||
File_Externally_Modified_Function *hook_file_externally_modified;
|
||||
Command_Caller_Hook_Function *command_caller;
|
||||
Render_Caller_Function *render_caller;
|
||||
|
|
17
4ed_edit.cpp
17
4ed_edit.cpp
|
@ -13,7 +13,6 @@ internal void
|
|||
edit_pre_state_change(Models *models, Editing_File *file){
|
||||
System_Functions *system = models->system;
|
||||
file_add_dirty_flag(file, DirtyState_UnsavedChanges);
|
||||
file_unmark_edit_finished(&models->working_set, file);
|
||||
}
|
||||
|
||||
internal void
|
||||
|
@ -191,10 +190,10 @@ edit_single(Models *models, Editing_File *file, Interval_i64 range, String_Const
|
|||
Assert(edit.range.one_past_last <= buffer_size(buffer));
|
||||
|
||||
Arena *scratch = &models->mem.arena;
|
||||
Temp_Memory temp = begin_temp(scratch);
|
||||
|
||||
// NOTE(allen): history update
|
||||
if (!behaviors.do_not_post_to_history){
|
||||
// TODO(allen): if the edit number counter is not updated, maybe auto-merge edits? Wouldn't that just work?
|
||||
history_dump_records_after_index(&file->state.history, file->state.current_record_index);
|
||||
history_record_edit(&models->global_history, &file->state.history, buffer, edit);
|
||||
file->state.current_record_index = history_get_record_count(&file->state.history);
|
||||
|
@ -203,9 +202,10 @@ edit_single(Models *models, Editing_File *file, Interval_i64 range, String_Const
|
|||
// NOTE(allen): fixing stuff beforewards????
|
||||
edit_pre_state_change(models, file);
|
||||
|
||||
// NOTE(allen): edit range hook
|
||||
// NOTE(allen): save the original text for the edit range hook.
|
||||
String_Const_u8 original_text = {};
|
||||
if (models->hook_file_edit_range != 0){
|
||||
models->hook_file_edit_range(&models->app_links, file->id, edit.range, edit.text);
|
||||
original_text = buffer_stringify(scratch, &file->state.buffer, edit.range);
|
||||
}
|
||||
|
||||
// NOTE(allen): expand spec, compute shift
|
||||
|
@ -227,8 +227,13 @@ edit_single(Models *models, Editing_File *file, Interval_i64 range, String_Const
|
|||
// NOTE(allen): cursor fixing
|
||||
edit_fix_markers(models, file, edit);
|
||||
|
||||
// NOTE(allen): mark edit finished
|
||||
file_mark_edit_finished(&models->working_set, file);
|
||||
// NOTE(allen): edit range hook
|
||||
if (models->hook_file_edit_range != 0){
|
||||
Interval_i64 new_range = Ii64(edit.range.first, edit.range.first + edit.text.size);
|
||||
models->hook_file_edit_range(&models->app_links, file->id, new_range, original_text);
|
||||
}
|
||||
|
||||
end_temp(temp);
|
||||
}
|
||||
|
||||
internal void
|
||||
|
|
|
@ -233,8 +233,6 @@ file_create_from_string(Models *models, Editing_File *file, String_Const_u8 val,
|
|||
file->lifetime_object = lifetime_alloc_object(&models->lifetime_allocator, DynamicWorkspace_Buffer, file);
|
||||
history_init(&models->app_links, &file->state.history);
|
||||
|
||||
file_mark_edit_finished(&models->working_set, file);
|
||||
|
||||
file->state.cached_layouts_arena = make_arena(allocator);
|
||||
file->state.line_layout_table = make_table_Data_u64(allocator, 500);
|
||||
|
||||
|
@ -272,8 +270,6 @@ file_free(System_Functions *system, Lifetime_Allocator *lifetime_allocator, Work
|
|||
|
||||
linalloc_clear(&file->state.cached_layouts_arena);
|
||||
table_free(&file->state.line_layout_table);
|
||||
|
||||
file_unmark_edit_finished(working_set, file);
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
|
|
|
@ -83,8 +83,6 @@ struct Editing_File{
|
|||
};
|
||||
Node touch_node;
|
||||
Node external_mod_node;
|
||||
Node edit_finished_mark_node;
|
||||
b32 edit_finished_marked;
|
||||
b32 is_loading;
|
||||
Buffer_ID id;
|
||||
Editing_File_Settings settings;
|
||||
|
|
|
@ -125,9 +125,6 @@ working_set_init(Models *models, Working_Set *working_set){
|
|||
dll_init_sentinel(&working_set->active_file_sentinel);
|
||||
dll_init_sentinel(&working_set->touch_order_sentinel);
|
||||
|
||||
dll_init_sentinel(&working_set->edit_finished_sentinel);
|
||||
working_set->edit_finished_timer = system->wake_up_timer_create();
|
||||
|
||||
local_const i32 slot_count = 128;
|
||||
Base_Allocator *allocator = get_base_allocator_system(system);
|
||||
working_set->id_to_ptr_table = make_table_u64_u64(allocator, slot_count);
|
||||
|
@ -502,36 +499,6 @@ file_get_next(Working_Set *working_set, Editing_File *file){
|
|||
return(file);
|
||||
}
|
||||
|
||||
internal void
|
||||
file_mark_edit_finished(Working_Set *working_set, Editing_File *file){
|
||||
// TODO(allen): do(propogate do_not_mark_edits down the edit pipeline to here)
|
||||
// This current method only works for synchronous calls, asynchronous calls
|
||||
// will get the wrong do_not_mark_edits value.
|
||||
if (!working_set->do_not_mark_edits){
|
||||
if (!file->edit_finished_marked){
|
||||
file->edit_finished_marked = true;
|
||||
dll_insert_back(&working_set->edit_finished_sentinel,
|
||||
&file->edit_finished_mark_node);
|
||||
working_set->edit_finished_count += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal b32
|
||||
file_unmark_edit_finished(Working_Set *working_set, Editing_File *file){
|
||||
b32 result = false;
|
||||
if (!working_set->do_not_mark_edits){
|
||||
if (file->edit_finished_marked){
|
||||
file->edit_finished_marked = false;
|
||||
dll_remove(&file->edit_finished_mark_node);
|
||||
working_set->edit_finished_count -= 1;
|
||||
block_zero_struct(&file->edit_finished_mark_node);
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
return(result);
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
|
||||
internal Editing_File*
|
||||
|
|
|
@ -26,12 +26,6 @@ struct Working_Set{
|
|||
Node touch_order_sentinel;
|
||||
i32 active_file_count;
|
||||
|
||||
Node edit_finished_sentinel;
|
||||
i32 edit_finished_count;
|
||||
u64 time_of_next_edit_finished_signal;
|
||||
Plat_Handle edit_finished_timer;
|
||||
b32 do_not_mark_edits;
|
||||
|
||||
Table_u64_u64 id_to_ptr_table;
|
||||
Table_Data_u64 canon_table;
|
||||
Table_Data_u64 name_table;
|
||||
|
@ -51,12 +45,6 @@ struct Working_Set{
|
|||
i32 clipboard_rolling;
|
||||
};
|
||||
|
||||
internal void
|
||||
file_mark_edit_finished(Working_Set *working_set, Editing_File *file);
|
||||
|
||||
internal b32
|
||||
file_unmark_edit_finished(Working_Set *working_set, Editing_File *file);
|
||||
|
||||
#endif
|
||||
|
||||
// BOTTOM
|
||||
|
|
Loading…
Reference in New Issue