diff --git a/code/custom/4coder_code_index.cpp b/code/custom/4coder_code_index.cpp index ace1bdd1..f83b5d1e 100644 --- a/code/custom/4coder_code_index.cpp +++ b/code/custom/4coder_code_index.cpp @@ -13,50 +13,50 @@ global Code_Index global_code_index = {}; // Looks like the only one I ever actually use is the file one, not the array one. function Code_Index_Nest* code_index_get_nest_(Code_Index_Nest_Ptr_Array *array, i64 pos){ -Code_Index_Nest *result = 0; -i32 count = array->count; -Code_Index_Nest **nest_ptrs = array->ptrs; -for (i32 i = 0; i < count; i += 1){ -Code_Index_Nest *nest = nest_ptrs[i]; -if (nest->open.max <= pos && pos <= nest->close.min){ -Code_Index_Nest *sub_nest = code_index_get_nest_(&nest->nest_array, pos); -if (sub_nest != 0){ -result = sub_nest; -} -else{ -result = nest; -} -break; -} -} -return(result); + Code_Index_Nest *result = 0; + i32 count = array->count; + Code_Index_Nest **nest_ptrs = array->ptrs; + for (i32 i = 0; i < count; i += 1){ + Code_Index_Nest *nest = nest_ptrs[i]; + if (nest->open.max <= pos && pos <= nest->close.min){ + Code_Index_Nest *sub_nest = code_index_get_nest_(&nest->nest_array, pos); + if (sub_nest != 0){ + result = sub_nest; + } + else{ + result = nest; + } + break; + } + } + return(result); } function Code_Index_Nest* code_index_get_nest(Code_Index_File *file, i64 pos){ -return(code_index_get_nest_(&file->nest_array, pos)); + return(code_index_get_nest_(&file->nest_array, pos)); } function Code_Index_Note_List* code_index__list_from_string(String_Const_u8 string){ -u64 hash = table_hash_u8(string.str, string.size); -Code_Index_Note_List *result = &global_code_index.name_hash[hash % ArrayCount(global_code_index.name_hash)]; -return(result); + u64 hash = table_hash_u8(string.str, string.size); + Code_Index_Note_List *result = &global_code_index.name_hash[hash % ArrayCount(global_code_index.name_hash)]; + return(result); } function Code_Index_Note* code_index_note_from_string(String_Const_u8 string){ -Code_Index_Note_List *list = code_index__list_from_string(string); -Code_Index_Note *result = 0; -for (Code_Index_Note *node = list->first; - node != 0; - node = node->next_in_hash){ -if (string_match(string, node->text)){ -result = node; -break; -} -} -return(result); + Code_Index_Note_List *list = code_index__list_from_string(string); + Code_Index_Note *result = 0; + for (Code_Index_Note *node = list->first; + node != 0; + node = node->next_in_hash){ + if (string_match(string, node->text)){ + result = node; + break; + } + } + return(result); } @@ -65,181 +65,181 @@ return(result); function void code_index_init(void){ -global_code_index.mutex = system_mutex_make(); -global_code_index.node_arena = make_arena_system(KB(4)); -global_code_index.buffer_to_index_file = make_table_u64_u64(global_code_index.node_arena.base_allocator, 500); + global_code_index.mutex = system_mutex_make(); + global_code_index.node_arena = make_arena_system(KB(4)); + global_code_index.buffer_to_index_file = make_table_u64_u64(global_code_index.node_arena.base_allocator, 500); } function Code_Index_File_Storage* code_index__alloc_storage(void){ -Code_Index_File_Storage *result = global_code_index.free_storage; -if (result == 0){ -result = push_array_zero(&global_code_index.node_arena, Code_Index_File_Storage, 1); -} -else{ -sll_stack_pop(global_code_index.free_storage); -} -zdll_push_back(global_code_index.storage_first, global_code_index.storage_last, result); -global_code_index.storage_count += 1; -return(result); + Code_Index_File_Storage *result = global_code_index.free_storage; + if (result == 0){ + result = push_array_zero(&global_code_index.node_arena, Code_Index_File_Storage, 1); + } + else{ + sll_stack_pop(global_code_index.free_storage); + } + zdll_push_back(global_code_index.storage_first, global_code_index.storage_last, result); + global_code_index.storage_count += 1; + return(result); } function void code_index__free_storage(Code_Index_File_Storage *storage){ -zdll_remove(global_code_index.storage_first, global_code_index.storage_last, storage); -global_code_index.storage_count -= 1; -sll_stack_push(global_code_index.free_storage, storage); + zdll_remove(global_code_index.storage_first, global_code_index.storage_last, storage); + global_code_index.storage_count -= 1; + sll_stack_push(global_code_index.free_storage, storage); } function void code_index_push_nest(Code_Index_Nest_List *list, Code_Index_Nest *nest){ -sll_queue_push(list->first, list->last, nest); -list->count += 1; + sll_queue_push(list->first, list->last, nest); + list->count += 1; } function Code_Index_Nest_Ptr_Array code_index_nest_ptr_array_from_list(Arena *arena, Code_Index_Nest_List *list){ -Code_Index_Nest_Ptr_Array array = {}; -array.ptrs = push_array_zero(arena, Code_Index_Nest*, list->count); -array.count = list->count; -i32 counter = 0; -for (Code_Index_Nest *node = list->first; - node != 0; - node = node->next){ -array.ptrs[counter] = node; -counter += 1; -} -return(array); + Code_Index_Nest_Ptr_Array array = {}; + array.ptrs = push_array_zero(arena, Code_Index_Nest*, list->count); + array.count = list->count; + i32 counter = 0; + for (Code_Index_Nest *node = list->first; + node != 0; + node = node->next){ + array.ptrs[counter] = node; + counter += 1; + } + return(array); } function Code_Index_Note_Ptr_Array code_index_note_ptr_array_from_list(Arena *arena, Code_Index_Note_List *list){ -Code_Index_Note_Ptr_Array array = {}; -array.ptrs = push_array_zero(arena, Code_Index_Note*, list->count); -array.count = list->count; -i32 counter = 0; -for (Code_Index_Note *node = list->first; - node != 0; - node = node->next){ -array.ptrs[counter] = node; -counter += 1; -} -return(array); + Code_Index_Note_Ptr_Array array = {}; + array.ptrs = push_array_zero(arena, Code_Index_Note*, list->count); + array.count = list->count; + i32 counter = 0; + for (Code_Index_Note *node = list->first; + node != 0; + node = node->next){ + array.ptrs[counter] = node; + counter += 1; + } + return(array); } function void code_index_lock(void){ -system_mutex_acquire(global_code_index.mutex); + system_mutex_acquire(global_code_index.mutex); } function void code_index_unlock(void){ -system_mutex_release(global_code_index.mutex); + system_mutex_release(global_code_index.mutex); } function void code_index__hash_file(Code_Index_File *file){ -for (Code_Index_Note *node = file->note_list.first; - node != 0; - node = node->next){ -Code_Index_Note_List *list = code_index__list_from_string(node->text); -zdll_push_back_NP_(list->first, list->last, node, next_in_hash, prev_in_hash); -list->count += 1; -} + for (Code_Index_Note *node = file->note_list.first; + node != 0; + node = node->next){ + Code_Index_Note_List *list = code_index__list_from_string(node->text); + zdll_push_back_NP_(list->first, list->last, node, next_in_hash, prev_in_hash); + list->count += 1; + } } function void code_index__clear_file(Code_Index_File *file){ -for (Code_Index_Note *node = file->note_list.first; - node != 0; - node = node->next){ -Code_Index_Note_List *list = code_index__list_from_string(node->text); -zdll_remove_NP_(list->first, list->last, node, next_in_hash, prev_in_hash); -list->count -= 1; -} + for (Code_Index_Note *node = file->note_list.first; + node != 0; + node = node->next){ + Code_Index_Note_List *list = code_index__list_from_string(node->text); + zdll_remove_NP_(list->first, list->last, node, next_in_hash, prev_in_hash); + list->count -= 1; + } } function void code_index_set_file(Buffer_ID buffer, Arena arena, Code_Index_File *index){ -Code_Index_File_Storage *storage = 0; -Table_Lookup lookup = table_lookup(&global_code_index.buffer_to_index_file, buffer); -if (lookup.found_match){ -u64 val = 0; -table_read(&global_code_index.buffer_to_index_file, lookup, &val); -storage = (Code_Index_File_Storage*)IntAsPtr(val); -code_index__clear_file(storage->file); -linalloc_clear(&storage->arena); -} -else{ -storage = code_index__alloc_storage(); -table_insert(&global_code_index.buffer_to_index_file, buffer, (u64)PtrAsInt(storage)); -} -storage->arena = arena; -storage->file = index; + Code_Index_File_Storage *storage = 0; + Table_Lookup lookup = table_lookup(&global_code_index.buffer_to_index_file, buffer); + if (lookup.found_match){ + u64 val = 0; + table_read(&global_code_index.buffer_to_index_file, lookup, &val); + storage = (Code_Index_File_Storage*)IntAsPtr(val); + code_index__clear_file(storage->file); + linalloc_clear(&storage->arena); + } + else{ + storage = code_index__alloc_storage(); + table_insert(&global_code_index.buffer_to_index_file, buffer, (u64)PtrAsInt(storage)); + } + storage->arena = arena; + storage->file = index; -code_index__hash_file(index); + code_index__hash_file(index); } function void code_index_erase_file(Buffer_ID buffer){ -Table_Lookup lookup = table_lookup(&global_code_index.buffer_to_index_file, buffer); -if (lookup.found_match){ -u64 val = 0; -table_read(&global_code_index.buffer_to_index_file, lookup, &val); -Code_Index_File_Storage *storage = (Code_Index_File_Storage*)IntAsPtr(val); + Table_Lookup lookup = table_lookup(&global_code_index.buffer_to_index_file, buffer); + if (lookup.found_match){ + u64 val = 0; + table_read(&global_code_index.buffer_to_index_file, lookup, &val); + Code_Index_File_Storage *storage = (Code_Index_File_Storage*)IntAsPtr(val); -code_index__clear_file(storage->file); + code_index__clear_file(storage->file); -linalloc_clear(&storage->arena); -table_erase(&global_code_index.buffer_to_index_file, lookup); -code_index__free_storage(storage); -} + linalloc_clear(&storage->arena); + table_erase(&global_code_index.buffer_to_index_file, lookup); + code_index__free_storage(storage); + } } function Code_Index_File* code_index_get_file(Buffer_ID buffer){ -Code_Index_File *result = 0; -Table_Lookup lookup = table_lookup(&global_code_index.buffer_to_index_file, buffer); -if (lookup.found_match){ -u64 val = 0; -table_read(&global_code_index.buffer_to_index_file, lookup, &val); -Code_Index_File_Storage *storage = (Code_Index_File_Storage*)IntAsPtr(val); -result = storage->file; -} -return(result); + Code_Index_File *result = 0; + Table_Lookup lookup = table_lookup(&global_code_index.buffer_to_index_file, buffer); + if (lookup.found_match){ + u64 val = 0; + table_read(&global_code_index.buffer_to_index_file, lookup, &val); + Code_Index_File_Storage *storage = (Code_Index_File_Storage*)IntAsPtr(val); + result = storage->file; + } + return(result); } function void index_shift(i64 *ptr, Range_i64 old_range, u64 new_size){ -i64 i = *ptr; -if (old_range.min <= i && i < old_range.max){ -*ptr = old_range.first; -} -else if (old_range.max <= i){ -*ptr = i + new_size - (old_range.max - old_range.min); -} + i64 i = *ptr; + if (old_range.min <= i && i < old_range.max){ + *ptr = old_range.first; + } + else if (old_range.max <= i){ + *ptr = i + new_size - (old_range.max - old_range.min); + } } function void code_index_shift(Code_Index_Nest_Ptr_Array *array, Range_i64 old_range, u64 new_size){ -i32 count = array->count; -Code_Index_Nest **nest_ptr = array->ptrs; -for (i32 i = 0; i < count; i += 1, nest_ptr += 1){ -Code_Index_Nest *nest = *nest_ptr; -index_shift(&nest->open.min, old_range, new_size); -index_shift(&nest->open.max, old_range, new_size); -if (nest->is_closed){ -index_shift(&nest->close.min, old_range, new_size); -index_shift(&nest->close.max, old_range, new_size); -} -code_index_shift(&nest->nest_array, old_range, new_size); -} + i32 count = array->count; + Code_Index_Nest **nest_ptr = array->ptrs; + for (i32 i = 0; i < count; i += 1, nest_ptr += 1){ + Code_Index_Nest *nest = *nest_ptr; + index_shift(&nest->open.min, old_range, new_size); + index_shift(&nest->open.max, old_range, new_size); + if (nest->is_closed){ + index_shift(&nest->close.min, old_range, new_size); + index_shift(&nest->close.max, old_range, new_size); + } + code_index_shift(&nest->nest_array, old_range, new_size); + } } function void code_index_shift(Code_Index_File *file, Range_i64 old_range, u64 new_size){ -code_index_shift(&file->nest_array, old_range, new_size); + code_index_shift(&file->nest_array, old_range, new_size); } @@ -248,49 +248,49 @@ code_index_shift(&file->nest_array, old_range, new_size); function void generic_parse_inc(Generic_Parse_State *state){ -if (!token_it_inc_all(&state->it)){ -state->finished = true; -} + if (!token_it_inc_all(&state->it)){ + state->finished = true; + } } function void generic_parse_skip_soft_tokens(Code_Index_File *index, Generic_Parse_State *state){ -Token *token = token_it_read(&state->it); -for (;token != 0 && !state->finished;){ -if (state->in_preprocessor && !HasFlag(token->flags, TokenBaseFlag_PreprocessorBody)){ -break; -} -if (token->kind == TokenBaseKind_Comment){ -state->handle_comment(state->app, state->arena, index, token, state->contents); -} -else if (token->kind == TokenBaseKind_Whitespace){ -Range_i64 range = Ii64(token); -u8 *ptr = state->contents.str + range.one_past_last - 1; -for (i64 i = range.one_past_last - 1; - i >= range.first; - i -= 1, ptr -= 1){ -if (*ptr == '\n'){ -state->prev_line_start = ptr + 1; -break; -} -} -} -else{ -break; -} -generic_parse_inc(state); -token = token_it_read(&state->it); -} + Token *token = token_it_read(&state->it); + for (;token != 0 && !state->finished;){ + if (state->in_preprocessor && !HasFlag(token->flags, TokenBaseFlag_PreprocessorBody)){ + break; + } + if (token->kind == TokenBaseKind_Comment){ + state->handle_comment(state->app, state->arena, index, token, state->contents); + } + else if (token->kind == TokenBaseKind_Whitespace){ + Range_i64 range = Ii64(token); + u8 *ptr = state->contents.str + range.one_past_last - 1; + for (i64 i = range.one_past_last - 1; + i >= range.first; + i -= 1, ptr -= 1){ + if (*ptr == '\n'){ + state->prev_line_start = ptr + 1; + break; + } + } + } + else{ + break; + } + generic_parse_inc(state); + token = token_it_read(&state->it); + } } function void generic_parse_init(Application_Links *app, Arena *arena, String_Const_u8 contents, Token_Array *tokens, Generic_Parse_Comment_Function *handle_comment, Generic_Parse_State *state){ -state->app = app; -state->arena = arena; -state->contents = contents; -state->it = token_iterator(0, tokens); -state->handle_comment = handle_comment; -state->prev_line_start = contents.str; + state->app = app; + state->arena = arena; + state->contents = contents; + state->it = token_iterator(0, tokens); + state->handle_comment = handle_comment; + state->prev_line_start = contents.str; } //////////////////////////////// @@ -329,126 +329,126 @@ function: >"(" ["(" ")" | * - ("(" | ")")] ")" ("{" | ";") function Code_Index_Note* index_new_note(Code_Index_File *index, Generic_Parse_State *state, Range_i64 range, Code_Index_Note_Kind kind, Code_Index_Nest *parent){ -Code_Index_Note *result = push_array(state->arena, Code_Index_Note, 1); -sll_queue_push(index->note_list.first, index->note_list.last, result); -index->note_list.count += 1; -result->note_kind = kind; -result->pos = range; -result->text = push_string_copy(state->arena, string_substring(state->contents, range)); -result->file = index; -result->parent = parent; -return(result); + Code_Index_Note *result = push_array(state->arena, Code_Index_Note, 1); + sll_queue_push(index->note_list.first, index->note_list.last, result); + index->note_list.count += 1; + result->note_kind = kind; + result->pos = range; + result->text = push_string_copy(state->arena, string_substring(state->contents, range)); + result->file = index; + result->parent = parent; + return(result); } function void cpp_parse_type_structure(Code_Index_File *index, Generic_Parse_State *state, Code_Index_Nest *parent){ -generic_parse_inc(state); -generic_parse_skip_soft_tokens(index, state); -if (state->finished){ -return; -} -Token *token = token_it_read(&state->it); -if (token != 0 && token->kind == TokenBaseKind_Identifier){ -generic_parse_inc(state); -generic_parse_skip_soft_tokens(index, state); -Token *peek = token_it_read(&state->it); -if (peek != 0 && peek->kind == TokenBaseKind_StatementClose || - peek->kind == TokenBaseKind_ScopeOpen){ -index_new_note(index, state, Ii64(token), CodeIndexNote_Type, parent); -} -} + generic_parse_inc(state); + generic_parse_skip_soft_tokens(index, state); + if (state->finished){ + return; + } + Token *token = token_it_read(&state->it); + if (token != 0 && token->kind == TokenBaseKind_Identifier){ + generic_parse_inc(state); + generic_parse_skip_soft_tokens(index, state); + Token *peek = token_it_read(&state->it); + if (peek != 0 && peek->kind == TokenBaseKind_StatementClose || + peek->kind == TokenBaseKind_ScopeOpen){ + index_new_note(index, state, Ii64(token), CodeIndexNote_Type, parent); + } + } } function void cpp_parse_type_def(Code_Index_File *index, Generic_Parse_State *state, Code_Index_Nest *parent){ -generic_parse_inc(state); -generic_parse_skip_soft_tokens(index, state); -for (;;){ -b32 did_advance = false; -Token *token = token_it_read(&state->it); -if (token == 0 || state->finished){ -break; -} -if (token->kind == TokenBaseKind_Identifier){ -generic_parse_inc(state); -generic_parse_skip_soft_tokens(index, state); -did_advance = true; -Token *peek = token_it_read(&state->it); -if (peek != 0 && peek->kind == TokenBaseKind_StatementClose || - peek->kind == TokenBaseKind_ParentheticalOpen){ -index_new_note(index, state, Ii64(token), CodeIndexNote_Type, parent); -break; -} -} -else if (token->kind == TokenBaseKind_StatementClose || - token->kind == TokenBaseKind_ScopeOpen || - token->kind == TokenBaseKind_ScopeClose || - token->kind == TokenBaseKind_ScopeOpen || - token->kind == TokenBaseKind_ScopeClose){ -break; -} -else if (token->kind == TokenBaseKind_Keyword){ -String_Const_u8 lexeme = string_substring(state->contents, Ii64(token)); -if (string_match(lexeme, string_u8_litexpr("struct")) || - string_match(lexeme, string_u8_litexpr("union")) || - string_match(lexeme, string_u8_litexpr("enum"))){ -break; -} -} -if (!did_advance){ -generic_parse_inc(state); -generic_parse_skip_soft_tokens(index, state); -} -} + generic_parse_inc(state); + generic_parse_skip_soft_tokens(index, state); + for (;;){ + b32 did_advance = false; + Token *token = token_it_read(&state->it); + if (token == 0 || state->finished){ + break; + } + if (token->kind == TokenBaseKind_Identifier){ + generic_parse_inc(state); + generic_parse_skip_soft_tokens(index, state); + did_advance = true; + Token *peek = token_it_read(&state->it); + if (peek != 0 && peek->kind == TokenBaseKind_StatementClose || + peek->kind == TokenBaseKind_ParentheticalOpen){ + index_new_note(index, state, Ii64(token), CodeIndexNote_Type, parent); + break; + } + } + else if (token->kind == TokenBaseKind_StatementClose || + token->kind == TokenBaseKind_ScopeOpen || + token->kind == TokenBaseKind_ScopeClose || + token->kind == TokenBaseKind_ScopeOpen || + token->kind == TokenBaseKind_ScopeClose){ + break; + } + else if (token->kind == TokenBaseKind_Keyword){ + String_Const_u8 lexeme = string_substring(state->contents, Ii64(token)); + if (string_match(lexeme, string_u8_litexpr("struct")) || + string_match(lexeme, string_u8_litexpr("union")) || + string_match(lexeme, string_u8_litexpr("enum"))){ + break; + } + } + if (!did_advance){ + generic_parse_inc(state); + generic_parse_skip_soft_tokens(index, state); + } + } } function void cpp_parse_function(Code_Index_File *index, Generic_Parse_State *state, Code_Index_Nest *parent){ -Token *token = token_it_read(&state->it); -generic_parse_inc(state); -generic_parse_skip_soft_tokens(index, state); -if (state->finished){ -return; -} -Token *peek = token_it_read(&state->it); -Token *reset_point = peek; -if (peek != 0 && peek->sub_kind == TokenCppKind_ParenOp){ -b32 at_paren_close = false; -i32 paren_nest_level = 0; -for (; peek != 0;){ -generic_parse_inc(state); -generic_parse_skip_soft_tokens(index, state); -peek = token_it_read(&state->it); -if (peek == 0 || state->finished){ -break; -} + Token *token = token_it_read(&state->it); + generic_parse_inc(state); + generic_parse_skip_soft_tokens(index, state); + if (state->finished){ + return; + } + Token *peek = token_it_read(&state->it); + Token *reset_point = peek; + if (peek != 0 && peek->sub_kind == TokenCppKind_ParenOp){ + b32 at_paren_close = false; + i32 paren_nest_level = 0; + for (; peek != 0;){ + generic_parse_inc(state); + generic_parse_skip_soft_tokens(index, state); + peek = token_it_read(&state->it); + if (peek == 0 || state->finished){ + break; + } -if (peek->kind == TokenBaseKind_ParentheticalOpen){ -paren_nest_level += 1; -} -else if (peek->kind == TokenBaseKind_ParentheticalClose){ -if (paren_nest_level > 0){ -paren_nest_level -= 1; -} -else{ -at_paren_close = true; -break; -} -} -} + if (peek->kind == TokenBaseKind_ParentheticalOpen){ + paren_nest_level += 1; + } + else if (peek->kind == TokenBaseKind_ParentheticalClose){ + if (paren_nest_level > 0){ + paren_nest_level -= 1; + } + else{ + at_paren_close = true; + break; + } + } + } -if (at_paren_close){ -generic_parse_inc(state); -generic_parse_skip_soft_tokens(index, state); -peek = token_it_read(&state->it); -if (peek != 0 && - peek->kind == TokenBaseKind_ScopeOpen || - peek->kind == TokenBaseKind_StatementClose){ -index_new_note(index, state, Ii64(token), CodeIndexNote_Function, parent); -} -} -} -state->it = token_iterator(state->it.user_id, state->it.tokens, state->it.count, reset_point); + if (at_paren_close){ + generic_parse_inc(state); + generic_parse_skip_soft_tokens(index, state); + peek = token_it_read(&state->it); + if (peek != 0 && + peek->kind == TokenBaseKind_ScopeOpen || + peek->kind == TokenBaseKind_StatementClose){ + index_new_note(index, state, Ii64(token), CodeIndexNote_Function, parent); + } + } + } + state->it = token_iterator(state->it.user_id, state->it.tokens, state->it.count, reset_point); } function Code_Index_Nest* @@ -465,350 +465,350 @@ generic_parse_paren(Code_Index_File *index, Generic_Parse_State *state); function Code_Index_Nest* generic_parse_statement(Code_Index_File *index, Generic_Parse_State *state){ -Token *token = token_it_read(&state->it); -Code_Index_Nest *result = push_array_zero(state->arena, Code_Index_Nest, 1); -result->kind = CodeIndexNest_Statement; -result->open = Ii64(token->pos); -result->close = Ii64(max_i64); -result->file = index; + Token *token = token_it_read(&state->it); + Code_Index_Nest *result = push_array_zero(state->arena, Code_Index_Nest, 1); + result->kind = CodeIndexNest_Statement; + result->open = Ii64(token->pos); + result->close = Ii64(max_i64); + result->file = index; -state->in_statement = true; + state->in_statement = true; -for (;;){ -generic_parse_skip_soft_tokens(index, state); -token = token_it_read(&state->it); -if (token == 0 || state->finished){ -break; -} + for (;;){ + generic_parse_skip_soft_tokens(index, state); + token = token_it_read(&state->it); + if (token == 0 || state->finished){ + break; + } -if (state->in_preprocessor){ -if (!HasFlag(token->flags, TokenBaseFlag_PreprocessorBody) || - token->kind == TokenBaseKind_Preprocessor){ -result->is_closed = true; -result->close = Ii64(token->pos); -break; -} -} -else{ -if (token->kind == TokenBaseKind_Preprocessor){ -result->is_closed = true; -result->close = Ii64(token->pos); -break; -} -} + if (state->in_preprocessor){ + if (!HasFlag(token->flags, TokenBaseFlag_PreprocessorBody) || + token->kind == TokenBaseKind_Preprocessor){ + result->is_closed = true; + result->close = Ii64(token->pos); + break; + } + } + else{ + if (token->kind == TokenBaseKind_Preprocessor){ + result->is_closed = true; + result->close = Ii64(token->pos); + break; + } + } -if (token->kind == TokenBaseKind_ScopeOpen || - token->kind == TokenBaseKind_ScopeClose || - token->kind == TokenBaseKind_ParentheticalOpen){ -result->is_closed = true; -result->close = Ii64(token->pos); -break; -} + if (token->kind == TokenBaseKind_ScopeOpen || + token->kind == TokenBaseKind_ScopeClose || + token->kind == TokenBaseKind_ParentheticalOpen){ + result->is_closed = true; + result->close = Ii64(token->pos); + break; + } -if (token->kind == TokenBaseKind_StatementClose){ -result->is_closed = true; -result->close = Ii64(token); -generic_parse_inc(state); -break; -} + if (token->kind == TokenBaseKind_StatementClose){ + result->is_closed = true; + result->close = Ii64(token); + generic_parse_inc(state); + break; + } -generic_parse_inc(state); -} + generic_parse_inc(state); + } -state->in_statement = false; + state->in_statement = false; -return(result); + return(result); } function Code_Index_Nest* generic_parse_preprocessor(Code_Index_File *index, Generic_Parse_State *state){ -Token *token = token_it_read(&state->it); -Code_Index_Nest *result = push_array_zero(state->arena, Code_Index_Nest, 1); -result->kind = CodeIndexNest_Preprocessor; -result->open = Ii64(token->pos); -result->close = Ii64(max_i64); -result->file = index; + Token *token = token_it_read(&state->it); + Code_Index_Nest *result = push_array_zero(state->arena, Code_Index_Nest, 1); + result->kind = CodeIndexNest_Preprocessor; + result->open = Ii64(token->pos); + result->close = Ii64(max_i64); + result->file = index; -state->in_preprocessor = true; + state->in_preprocessor = true; -b32 potential_macro = false; -if (state->do_cpp_parse){ -if (token->sub_kind == TokenCppKind_PPDefine){ -potential_macro = true; -} -} + b32 potential_macro = false; + if (state->do_cpp_parse){ + if (token->sub_kind == TokenCppKind_PPDefine){ + potential_macro = true; + } + } -generic_parse_inc(state); -for (;;){ -generic_parse_skip_soft_tokens(index, state); -token = token_it_read(&state->it); -if (token == 0 || state->finished){ -break; -} + generic_parse_inc(state); + for (;;){ + generic_parse_skip_soft_tokens(index, state); + token = token_it_read(&state->it); + if (token == 0 || state->finished){ + break; + } -if (!HasFlag(token->flags, TokenBaseFlag_PreprocessorBody) || - token->kind == TokenBaseKind_Preprocessor){ -result->is_closed = true; -result->close = Ii64(token->pos); -break; -} + if (!HasFlag(token->flags, TokenBaseFlag_PreprocessorBody) || + token->kind == TokenBaseKind_Preprocessor){ + result->is_closed = true; + result->close = Ii64(token->pos); + break; + } -if (state->do_cpp_parse && potential_macro){ -if (token->sub_kind == TokenCppKind_Identifier){ -index_new_note(index, state, Ii64(token), CodeIndexNote_Macro, result); -} -potential_macro = false; -} + if (state->do_cpp_parse && potential_macro){ + if (token->sub_kind == TokenCppKind_Identifier){ + index_new_note(index, state, Ii64(token), CodeIndexNote_Macro, result); + } + potential_macro = false; + } -if (token->kind == TokenBaseKind_ScopeOpen){ -Code_Index_Nest *nest = generic_parse_scope(index, state); -nest->parent = result; -code_index_push_nest(&result->nest_list, nest); -continue; -} + if (token->kind == TokenBaseKind_ScopeOpen){ + Code_Index_Nest *nest = generic_parse_scope(index, state); + nest->parent = result; + code_index_push_nest(&result->nest_list, nest); + continue; + } -if (token->kind == TokenBaseKind_ParentheticalOpen){ -Code_Index_Nest *nest = generic_parse_paren(index, state); -nest->parent = result; -code_index_push_nest(&result->nest_list, nest); -continue; -} + if (token->kind == TokenBaseKind_ParentheticalOpen){ + Code_Index_Nest *nest = generic_parse_paren(index, state); + nest->parent = result; + code_index_push_nest(&result->nest_list, nest); + continue; + } -generic_parse_inc(state); -} + generic_parse_inc(state); + } -result->nest_array = code_index_nest_ptr_array_from_list(state->arena, &result->nest_list); + result->nest_array = code_index_nest_ptr_array_from_list(state->arena, &result->nest_list); -state->in_preprocessor = false; + state->in_preprocessor = false; -return(result); + return(result); } function Code_Index_Nest* generic_parse_scope(Code_Index_File *index, Generic_Parse_State *state){ -Token *token = token_it_read(&state->it); -Code_Index_Nest *result = push_array_zero(state->arena, Code_Index_Nest, 1); -result->kind = CodeIndexNest_Scope; -result->open = Ii64(token); -result->close = Ii64(max_i64); -result->file = index; + Token *token = token_it_read(&state->it); + Code_Index_Nest *result = push_array_zero(state->arena, Code_Index_Nest, 1); + result->kind = CodeIndexNest_Scope; + result->open = Ii64(token); + result->close = Ii64(max_i64); + result->file = index; -state->scope_counter += 1; + state->scope_counter += 1; -generic_parse_inc(state); -for (;;){ -generic_parse_skip_soft_tokens(index, state); -token = token_it_read(&state->it); -if (token == 0 || state->finished){ -break; -} + generic_parse_inc(state); + for (;;){ + generic_parse_skip_soft_tokens(index, state); + token = token_it_read(&state->it); + if (token == 0 || state->finished){ + break; + } -if (state->in_preprocessor){ -if (!HasFlag(token->flags, TokenBaseFlag_PreprocessorBody) || - token->kind == TokenBaseKind_Preprocessor){ -break; -} -} -else{ -if (token->kind == TokenBaseKind_Preprocessor){ -Code_Index_Nest *nest = generic_parse_preprocessor(index, state); -code_index_push_nest(&index->nest_list, nest); -continue; -} -} + if (state->in_preprocessor){ + if (!HasFlag(token->flags, TokenBaseFlag_PreprocessorBody) || + token->kind == TokenBaseKind_Preprocessor){ + break; + } + } + else{ + if (token->kind == TokenBaseKind_Preprocessor){ + Code_Index_Nest *nest = generic_parse_preprocessor(index, state); + code_index_push_nest(&index->nest_list, nest); + continue; + } + } -if (token->kind == TokenBaseKind_ScopeClose){ -result->is_closed = true; -result->close = Ii64(token); -generic_parse_inc(state); -break; -} + if (token->kind == TokenBaseKind_ScopeClose){ + result->is_closed = true; + result->close = Ii64(token); + generic_parse_inc(state); + break; + } -if (token->kind == TokenBaseKind_ScopeOpen){ -Code_Index_Nest *nest = generic_parse_scope(index, state); -nest->parent = result; -code_index_push_nest(&result->nest_list, nest); -continue; -} + if (token->kind == TokenBaseKind_ScopeOpen){ + Code_Index_Nest *nest = generic_parse_scope(index, state); + nest->parent = result; + code_index_push_nest(&result->nest_list, nest); + continue; + } -if (token->kind == TokenBaseKind_ParentheticalClose){ -generic_parse_inc(state); -continue; -} + if (token->kind == TokenBaseKind_ParentheticalClose){ + generic_parse_inc(state); + continue; + } -if (token->kind == TokenBaseKind_ParentheticalOpen){ -Code_Index_Nest *nest = generic_parse_paren(index, state); -nest->parent = result; -code_index_push_nest(&result->nest_list, nest); + if (token->kind == TokenBaseKind_ParentheticalOpen){ + Code_Index_Nest *nest = generic_parse_paren(index, state); + nest->parent = result; + code_index_push_nest(&result->nest_list, nest); -// NOTE(allen): after a parenthetical group we consider ourselves immediately -// transitioning into a statement -nest = generic_parse_statement(index, state); -nest->parent = result; -code_index_push_nest(&result->nest_list, nest); + // NOTE(allen): after a parenthetical group we consider ourselves immediately + // transitioning into a statement + nest = generic_parse_statement(index, state); + nest->parent = result; + code_index_push_nest(&result->nest_list, nest); -continue; -} + continue; + } -{ -Code_Index_Nest *nest = generic_parse_statement(index, state); -nest->parent = result; -code_index_push_nest(&result->nest_list, nest); -} -} + { + Code_Index_Nest *nest = generic_parse_statement(index, state); + nest->parent = result; + code_index_push_nest(&result->nest_list, nest); + } + } -result->nest_array = code_index_nest_ptr_array_from_list(state->arena, &result->nest_list); + result->nest_array = code_index_nest_ptr_array_from_list(state->arena, &result->nest_list); -state->scope_counter -= 1; + state->scope_counter -= 1; -return(result); + return(result); } function Code_Index_Nest* generic_parse_paren(Code_Index_File *index, Generic_Parse_State *state){ -Token *token = token_it_read(&state->it); -Code_Index_Nest *result = push_array_zero(state->arena, Code_Index_Nest, 1); -result->kind = CodeIndexNest_Paren; -result->open = Ii64(token); -result->close = Ii64(max_i64); -result->file = index; + Token *token = token_it_read(&state->it); + Code_Index_Nest *result = push_array_zero(state->arena, Code_Index_Nest, 1); + result->kind = CodeIndexNest_Paren; + result->open = Ii64(token); + result->close = Ii64(max_i64); + result->file = index; -i64 manifested_characters_on_line = 0; -{ -u8 *ptr = state->prev_line_start; -u8 *end_ptr = state->contents.str + token->pos; -// NOTE(allen): Initial whitespace -for (;ptr < end_ptr; ptr += 1){ -if (!character_is_whitespace(*ptr)){ -break; -} -} -// NOTE(allen): Manifested characters -manifested_characters_on_line = (i64)(end_ptr - ptr) + token->size; -} + i64 manifested_characters_on_line = 0; + { + u8 *ptr = state->prev_line_start; + u8 *end_ptr = state->contents.str + token->pos; + // NOTE(allen): Initial whitespace + for (;ptr < end_ptr; ptr += 1){ + if (!character_is_whitespace(*ptr)){ + break; + } + } + // NOTE(allen): Manifested characters + manifested_characters_on_line = (i64)(end_ptr - ptr) + token->size; + } -state->paren_counter += 1; + state->paren_counter += 1; -generic_parse_inc(state); -for (;;){ -generic_parse_skip_soft_tokens(index, state); -token = token_it_read(&state->it); -if (token == 0 || state->finished){ -break; -} + generic_parse_inc(state); + for (;;){ + generic_parse_skip_soft_tokens(index, state); + token = token_it_read(&state->it); + if (token == 0 || state->finished){ + break; + } -if (state->in_preprocessor){ -if (!HasFlag(token->flags, TokenBaseFlag_PreprocessorBody) || - token->kind == TokenBaseKind_Preprocessor){ -break; -} -} -else{ -if (token->kind == TokenBaseKind_Preprocessor){ -Code_Index_Nest *nest = generic_parse_preprocessor(index, state); -code_index_push_nest(&index->nest_list, nest); -continue; -} -} + if (state->in_preprocessor){ + if (!HasFlag(token->flags, TokenBaseFlag_PreprocessorBody) || + token->kind == TokenBaseKind_Preprocessor){ + break; + } + } + else{ + if (token->kind == TokenBaseKind_Preprocessor){ + Code_Index_Nest *nest = generic_parse_preprocessor(index, state); + code_index_push_nest(&index->nest_list, nest); + continue; + } + } -if (token->kind == TokenBaseKind_ParentheticalClose){ -result->is_closed = true; -result->close = Ii64(token); -generic_parse_inc(state); -break; -} + if (token->kind == TokenBaseKind_ParentheticalClose){ + result->is_closed = true; + result->close = Ii64(token); + generic_parse_inc(state); + break; + } -if (token->kind == TokenBaseKind_ScopeClose){ -break; -} + if (token->kind == TokenBaseKind_ScopeClose){ + break; + } -if (token->kind == TokenBaseKind_ScopeOpen){ -Code_Index_Nest *nest = generic_parse_scope(index, state); -nest->parent = result; -code_index_push_nest(&result->nest_list, nest); -continue; -} + if (token->kind == TokenBaseKind_ScopeOpen){ + Code_Index_Nest *nest = generic_parse_scope(index, state); + nest->parent = result; + code_index_push_nest(&result->nest_list, nest); + continue; + } -if (token->kind == TokenBaseKind_ParentheticalOpen){ -Code_Index_Nest *nest = generic_parse_paren(index, state); -nest->parent = result; -code_index_push_nest(&result->nest_list, nest); -continue; -} + if (token->kind == TokenBaseKind_ParentheticalOpen){ + Code_Index_Nest *nest = generic_parse_paren(index, state); + nest->parent = result; + code_index_push_nest(&result->nest_list, nest); + continue; + } -generic_parse_inc(state); -} + generic_parse_inc(state); + } -result->nest_array = code_index_nest_ptr_array_from_list(state->arena, &result->nest_list); + result->nest_array = code_index_nest_ptr_array_from_list(state->arena, &result->nest_list); -state->paren_counter -= 1; + state->paren_counter -= 1; -return(result); + return(result); } function b32 generic_parse_full_input_breaks(Code_Index_File *index, Generic_Parse_State *state, i32 limit){ -b32 result = false; + b32 result = false; -i64 first_index = token_it_index(&state->it); -i64 one_past_last_index = first_index + limit; -for (;;){ -generic_parse_skip_soft_tokens(index, state); -Token *token = token_it_read(&state->it); + i64 first_index = token_it_index(&state->it); + i64 one_past_last_index = first_index + limit; + for (;;){ + generic_parse_skip_soft_tokens(index, state); + Token *token = token_it_read(&state->it); -if (token == 0 || state->finished){ -result = true; -break; -} + if (token == 0 || state->finished){ + result = true; + break; + } -if (token->kind == TokenBaseKind_Preprocessor){ -Code_Index_Nest *nest = generic_parse_preprocessor(index, state); -code_index_push_nest(&index->nest_list, nest); -} -else if (token->kind == TokenBaseKind_ScopeOpen){ -Code_Index_Nest *nest = generic_parse_scope(index, state); -code_index_push_nest(&index->nest_list, nest); -} -else if (token->kind == TokenBaseKind_ParentheticalOpen){ -Code_Index_Nest *nest = generic_parse_paren(index, state); -code_index_push_nest(&index->nest_list, nest); -} -else if (state->do_cpp_parse){ -if (token->sub_kind == TokenCppKind_Struct || - token->sub_kind == TokenCppKind_Union || - token->sub_kind == TokenCppKind_Enum){ -cpp_parse_type_structure(index, state, 0); -} -else if (token->sub_kind == TokenCppKind_Typedef){ -cpp_parse_type_def(index, state, 0); -} -else if (token->sub_kind == TokenCppKind_Identifier){ -cpp_parse_function(index, state, 0); -} -else{ -generic_parse_inc(state); -} -} -else{ -generic_parse_inc(state); -} + if (token->kind == TokenBaseKind_Preprocessor){ + Code_Index_Nest *nest = generic_parse_preprocessor(index, state); + code_index_push_nest(&index->nest_list, nest); + } + else if (token->kind == TokenBaseKind_ScopeOpen){ + Code_Index_Nest *nest = generic_parse_scope(index, state); + code_index_push_nest(&index->nest_list, nest); + } + else if (token->kind == TokenBaseKind_ParentheticalOpen){ + Code_Index_Nest *nest = generic_parse_paren(index, state); + code_index_push_nest(&index->nest_list, nest); + } + else if (state->do_cpp_parse){ + if (token->sub_kind == TokenCppKind_Struct || + token->sub_kind == TokenCppKind_Union || + token->sub_kind == TokenCppKind_Enum){ + cpp_parse_type_structure(index, state, 0); + } + else if (token->sub_kind == TokenCppKind_Typedef){ + cpp_parse_type_def(index, state, 0); + } + else if (token->sub_kind == TokenCppKind_Identifier){ + cpp_parse_function(index, state, 0); + } + else{ + generic_parse_inc(state); + } + } + else{ + generic_parse_inc(state); + } -i64 index = token_it_index(&state->it); -if (index >= one_past_last_index){ -token = token_it_read(&state->it); -if (token == 0){ -result = true; -} -break; -} -} + i64 index = token_it_index(&state->it); + if (index >= one_past_last_index){ + token = token_it_read(&state->it); + if (token == 0){ + result = true; + } + break; + } + } -if (result){ -index->nest_array = code_index_nest_ptr_array_from_list(state->arena, &index->nest_list); -index->note_array = code_index_note_ptr_array_from_list(state->arena, &index->note_list); -} + if (result){ + index->nest_array = code_index_nest_ptr_array_from_list(state->arena, &index->nest_list); + index->note_array = code_index_note_ptr_array_from_list(state->arena, &index->note_list); + } -return(result); + return(result); } @@ -822,7 +822,7 @@ default_comment_index(Application_Links *app, Arena *arena, Code_Index_File *ind function void generic_parse_init(Application_Links *app, Arena *arena, String_Const_u8 contents, Token_Array *tokens, Generic_Parse_State *state){ -generic_parse_init(app, arena, contents, tokens, default_comment_index, state); + generic_parse_init(app, arena, contents, tokens, default_comment_index, state); } @@ -831,416 +831,416 @@ generic_parse_init(app, arena, contents, tokens, default_comment_index, state); function Token_Pair layout_token_pair(Token_Array *tokens, i64 pos){ -Token_Pair result = {}; -Token_Iterator_Array it = token_iterator_pos(0, tokens, pos); -Token *b = token_it_read(&it); -if (b != 0){ -if (b->kind == TokenBaseKind_Whitespace){ -token_it_inc_non_whitespace(&it); -b = token_it_read(&it); -} -} -token_it_dec_non_whitespace(&it); -Token *a = token_it_read(&it); -if (a != 0){ -result.a = *a; -} -if (b != 0){ -result.b = *b; -} -return(result); + Token_Pair result = {}; + Token_Iterator_Array it = token_iterator_pos(0, tokens, pos); + Token *b = token_it_read(&it); + if (b != 0){ + if (b->kind == TokenBaseKind_Whitespace){ + token_it_inc_non_whitespace(&it); + b = token_it_read(&it); + } + } + token_it_dec_non_whitespace(&it); + Token *a = token_it_read(&it); + if (a != 0){ + result.a = *a; + } + if (b != 0){ + result.b = *b; + } + return(result); } function f32 layout_index_x_shift(Application_Links *app, Layout_Reflex *reflex, Code_Index_Nest *nest, i64 pos, f32 regular_indent, b32 *unresolved_dependence){ -f32 result = 0.f; -if (nest != 0){ -switch (nest->kind){ -case CodeIndexNest_Scope: -case CodeIndexNest_Preprocessor: -{ -result = layout_index_x_shift(app, reflex, nest->parent, pos, regular_indent, unresolved_dependence); -if (nest->open.min < pos && nest->open.max <= pos && - (!nest->is_closed || pos < nest->close.min)){ -result += regular_indent; -} -}break; + f32 result = 0.f; + if (nest != 0){ + switch (nest->kind){ + case CodeIndexNest_Scope: + case CodeIndexNest_Preprocessor: + { + result = layout_index_x_shift(app, reflex, nest->parent, pos, regular_indent, unresolved_dependence); + if (nest->open.min < pos && nest->open.max <= pos && + (!nest->is_closed || pos < nest->close.min)){ + result += regular_indent; + } + }break; -case CodeIndexNest_Statement: -{ -result = layout_index_x_shift(app, reflex, nest->parent, pos, regular_indent, unresolved_dependence); -if (nest->open.min < pos && nest->open.max <= pos && - (!nest->is_closed || pos < nest->close.min)){ -result += regular_indent; -} -}break; + case CodeIndexNest_Statement: + { + result = layout_index_x_shift(app, reflex, nest->parent, pos, regular_indent, unresolved_dependence); + if (nest->open.min < pos && nest->open.max <= pos && + (!nest->is_closed || pos < nest->close.min)){ + result += regular_indent; + } + }break; -case CodeIndexNest_Paren: -{ -Rect_f32 box = layout_reflex_get_rect(app, reflex, nest->open.max - 1, unresolved_dependence); -result = box.x1; -}break; -} -} -return(result); + case CodeIndexNest_Paren: + { + Rect_f32 box = layout_reflex_get_rect(app, reflex, nest->open.max - 1, unresolved_dependence); + result = box.x1; + }break; + } + } + return(result); } function f32 layout_index_x_shift(Application_Links *app, Layout_Reflex *reflex, Code_Index_Nest *nest, i64 pos, f32 regular_indent){ -b32 ignore; -return(layout_index_x_shift(app, reflex, nest, pos, regular_indent, &ignore)); + b32 ignore; + return(layout_index_x_shift(app, reflex, nest, pos, regular_indent, &ignore)); } function f32 layout_index_x_shift(Application_Links *app, Layout_Reflex *reflex, Code_Index_File *file, i64 pos, f32 regular_indent, b32 *unresolved_dependence){ -f32 indent = 0; -Code_Index_Nest *nest = code_index_get_nest(file, pos); -if (nest != 0){ -indent = layout_index_x_shift(app, reflex, nest, pos, regular_indent, unresolved_dependence); -} -return(indent); + f32 indent = 0; + Code_Index_Nest *nest = code_index_get_nest(file, pos); + if (nest != 0){ + indent = layout_index_x_shift(app, reflex, nest, pos, regular_indent, unresolved_dependence); + } + return(indent); } function f32 layout_index_x_shift(Application_Links *app, Layout_Reflex *reflex, Code_Index_File *file, i64 pos, f32 regular_indent){ -b32 ignore; -return(layout_index_x_shift(app, reflex, file, pos, regular_indent, &ignore)); + b32 ignore; + return(layout_index_x_shift(app, reflex, file, pos, regular_indent, &ignore)); } function void layout_index__emit_chunk(LefRig_TopBot_Layout_Vars *pos_vars, Face_ID face, Arena *arena, u8 *text_str, i64 range_first, u8 *ptr, u8 *end, Layout_Item_List *list){ -for (;ptr < end;){ -Character_Consume_Result consume = utf8_consume(ptr, (u64)(end - ptr)); -if (consume.codepoint != '\r'){ -i64 index = layout_index_from_ptr(ptr, text_str, range_first); -if (consume.codepoint != max_u32){ -lr_tb_write(pos_vars, face, arena, list, index, consume.codepoint); -} -else{ -lr_tb_write_byte(pos_vars, face, arena, list, index, *ptr); -} -} -ptr += consume.inc; -} + for (;ptr < end;){ + Character_Consume_Result consume = utf8_consume(ptr, (u64)(end - ptr)); + if (consume.codepoint != '\r'){ + i64 index = layout_index_from_ptr(ptr, text_str, range_first); + if (consume.codepoint != max_u32){ + lr_tb_write(pos_vars, face, arena, list, index, consume.codepoint); + } + else{ + lr_tb_write_byte(pos_vars, face, arena, list, index, *ptr); + } + } + ptr += consume.inc; + } } function i32 layout_token_score_wrap_token(Token_Pair *pair, Token_Cpp_Kind kind){ -i32 result = 0; -if (pair->a.sub_kind != kind && pair->b.sub_kind == kind){ -result -= 1; -} -else if (pair->a.sub_kind == kind && pair->b.sub_kind != kind){ -result += 1; -} -return(result); + i32 result = 0; + if (pair->a.sub_kind != kind && pair->b.sub_kind == kind){ + result -= 1; + } + else if (pair->a.sub_kind == kind && pair->b.sub_kind != kind){ + result += 1; + } + return(result); } function Layout_Item_List layout_index__inner(Application_Links *app, Arena *arena, Buffer_ID buffer, Range_i64 range, Face_ID face, f32 width, Code_Index_File *file, Layout_Wrap_Kind kind){ -Scratch_Block scratch(app, arena); + Scratch_Block scratch(app, arena); -Token_Array tokens = get_token_array_from_buffer(app, buffer); -Token_Array *tokens_ptr = &tokens; + Token_Array tokens = get_token_array_from_buffer(app, buffer); + Token_Array *tokens_ptr = &tokens; -Layout_Item_List list = get_empty_item_list(range); -String_Const_u8 text = push_buffer_range(app, scratch, buffer, range); + Layout_Item_List list = get_empty_item_list(range); + String_Const_u8 text = push_buffer_range(app, scratch, buffer, range); -Face_Advance_Map advance_map = get_face_advance_map(app, face); -Face_Metrics metrics = get_face_metrics(app, face); -f32 tab_width = (f32)def_get_config_u64(app, vars_save_string_lit("default_tab_width")); -tab_width = clamp_bot(1, tab_width); -LefRig_TopBot_Layout_Vars pos_vars = get_lr_tb_layout_vars(&advance_map, &metrics, tab_width, width); + Face_Advance_Map advance_map = get_face_advance_map(app, face); + Face_Metrics metrics = get_face_metrics(app, face); + f32 tab_width = (f32)def_get_config_u64(app, vars_save_string_lit("default_tab_width")); + tab_width = clamp_bot(1, tab_width); + LefRig_TopBot_Layout_Vars pos_vars = get_lr_tb_layout_vars(&advance_map, &metrics, tab_width, width); -u64 vw_indent = def_get_config_u64(app, vars_save_string_lit("virtual_whitespace_regular_indent")); -f32 regular_indent = metrics.space_advance*vw_indent; -f32 wrap_align_x = width - metrics.normal_advance; + u64 vw_indent = def_get_config_u64(app, vars_save_string_lit("virtual_whitespace_regular_indent")); + f32 regular_indent = metrics.space_advance*vw_indent; + f32 wrap_align_x = width - metrics.normal_advance; -Layout_Reflex reflex = get_layout_reflex(&list, buffer, width, face); + Layout_Reflex reflex = get_layout_reflex(&list, buffer, width, face); -if (text.size == 0){ -lr_tb_write_blank(&pos_vars, face, arena, &list, range.start); -} -else{ -b32 first_of_the_line = true; -Newline_Layout_Vars newline_vars = get_newline_layout_vars(); + if (text.size == 0){ + lr_tb_write_blank(&pos_vars, face, arena, &list, range.start); + } + else{ + b32 first_of_the_line = true; + Newline_Layout_Vars newline_vars = get_newline_layout_vars(); -u8 *ptr = text.str; -u8 *end_ptr = ptr + text.size; -u8 *word_ptr = ptr; + u8 *ptr = text.str; + u8 *end_ptr = ptr + text.size; + u8 *word_ptr = ptr; -u8 *pending_wrap_ptr = ptr; -f32 pending_wrap_x = 0.f; -i32 pending_wrap_paren_nest_count = 0; -i32 pending_wrap_token_score = 0; -f32 pending_wrap_accumulated_w = 0.f; + u8 *pending_wrap_ptr = ptr; + f32 pending_wrap_x = 0.f; + i32 pending_wrap_paren_nest_count = 0; + i32 pending_wrap_token_score = 0; + f32 pending_wrap_accumulated_w = 0.f; -start: -if (ptr == end_ptr){ -i64 index = layout_index_from_ptr(ptr, text.str, range.first); -f32 shift = layout_index_x_shift(app, &reflex, file, index, regular_indent); -lr_tb_advance_x_without_item(&pos_vars, shift); -goto finish; -} + start: + if (ptr == end_ptr){ + i64 index = layout_index_from_ptr(ptr, text.str, range.first); + f32 shift = layout_index_x_shift(app, &reflex, file, index, regular_indent); + lr_tb_advance_x_without_item(&pos_vars, shift); + goto finish; + } -if (!character_is_whitespace(*ptr)){ -i64 index = layout_index_from_ptr(ptr, text.str, range.first); -f32 shift = layout_index_x_shift(app, &reflex, file, index, regular_indent); -lr_tb_advance_x_without_item(&pos_vars, shift); -goto consuming_non_whitespace; -} + if (!character_is_whitespace(*ptr)){ + i64 index = layout_index_from_ptr(ptr, text.str, range.first); + f32 shift = layout_index_x_shift(app, &reflex, file, index, regular_indent); + lr_tb_advance_x_without_item(&pos_vars, shift); + goto consuming_non_whitespace; + } -{ -for (;ptr < end_ptr; ptr += 1){ -if (!character_is_whitespace(*ptr)){ -pending_wrap_ptr = ptr; -word_ptr = ptr; -i64 index = layout_index_from_ptr(ptr, text.str, range.first); -f32 shift = layout_index_x_shift(app, &reflex, file, index, regular_indent); -lr_tb_advance_x_without_item(&pos_vars, shift); -goto consuming_non_whitespace; -} -if (*ptr == '\r'){ -i64 index = layout_index_from_ptr(ptr, text.str, range.first); -newline_layout_consume_CR(&newline_vars, index); -} -else if (*ptr == '\n'){ -pending_wrap_ptr = ptr; -i64 index = layout_index_from_ptr(ptr, text.str, range.first); -f32 shift = layout_index_x_shift(app, &reflex, file, index, regular_indent); -lr_tb_advance_x_without_item(&pos_vars, shift); -goto consuming_normal_whitespace; -} -} + { + for (;ptr < end_ptr; ptr += 1){ + if (!character_is_whitespace(*ptr)){ + pending_wrap_ptr = ptr; + word_ptr = ptr; + i64 index = layout_index_from_ptr(ptr, text.str, range.first); + f32 shift = layout_index_x_shift(app, &reflex, file, index, regular_indent); + lr_tb_advance_x_without_item(&pos_vars, shift); + goto consuming_non_whitespace; + } + if (*ptr == '\r'){ + i64 index = layout_index_from_ptr(ptr, text.str, range.first); + newline_layout_consume_CR(&newline_vars, index); + } + else if (*ptr == '\n'){ + pending_wrap_ptr = ptr; + i64 index = layout_index_from_ptr(ptr, text.str, range.first); + f32 shift = layout_index_x_shift(app, &reflex, file, index, regular_indent); + lr_tb_advance_x_without_item(&pos_vars, shift); + goto consuming_normal_whitespace; + } + } -if (ptr == end_ptr){ -pending_wrap_ptr = ptr; -i64 index = layout_index_from_ptr(ptr - 1, text.str, range.first); -f32 shift = layout_index_x_shift(app, &reflex, file, index, regular_indent); -lr_tb_advance_x_without_item(&pos_vars, shift); -goto finish; -} -} + if (ptr == end_ptr){ + pending_wrap_ptr = ptr; + i64 index = layout_index_from_ptr(ptr - 1, text.str, range.first); + f32 shift = layout_index_x_shift(app, &reflex, file, index, regular_indent); + lr_tb_advance_x_without_item(&pos_vars, shift); + goto finish; + } + } -consuming_non_whitespace: -{ -for (;ptr <= end_ptr; ptr += 1){ -if (ptr == end_ptr || character_is_whitespace(*ptr)){ -break; -} -} + consuming_non_whitespace: + { + for (;ptr <= end_ptr; ptr += 1){ + if (ptr == end_ptr || character_is_whitespace(*ptr)){ + break; + } + } -// NOTE(allen): measure this word -newline_layout_consume_default(&newline_vars); -String_Const_u8 word = SCu8(word_ptr, ptr); -u8 *word_end = ptr; -{ -f32 word_advance = 0.f; -ptr = word.str; -for (;ptr < word_end;){ -Character_Consume_Result consume = utf8_consume(ptr, (u64)(word_end - ptr)); -if (consume.codepoint != max_u32){ -word_advance += lr_tb_advance(&pos_vars, face, consume.codepoint); -} -else{ -word_advance += lr_tb_advance_byte(&pos_vars); -} -ptr += consume.inc; -} -pending_wrap_accumulated_w += word_advance; -} + // NOTE(allen): measure this word + newline_layout_consume_default(&newline_vars); + String_Const_u8 word = SCu8(word_ptr, ptr); + u8 *word_end = ptr; + { + f32 word_advance = 0.f; + ptr = word.str; + for (;ptr < word_end;){ + Character_Consume_Result consume = utf8_consume(ptr, (u64)(word_end - ptr)); + if (consume.codepoint != max_u32){ + word_advance += lr_tb_advance(&pos_vars, face, consume.codepoint); + } + else{ + word_advance += lr_tb_advance_byte(&pos_vars); + } + ptr += consume.inc; + } + pending_wrap_accumulated_w += word_advance; + } -if (!first_of_the_line && (kind == Layout_Wrapped) && lr_tb_crosses_width(&pos_vars, pending_wrap_accumulated_w)){ -i64 index = layout_index_from_ptr(pending_wrap_ptr, text.str, range.first); -lr_tb_align_rightward(&pos_vars, wrap_align_x); -lr_tb_write_ghost(&pos_vars, face, arena, &list, index, '\\'); + if (!first_of_the_line && (kind == Layout_Wrapped) && lr_tb_crosses_width(&pos_vars, pending_wrap_accumulated_w)){ + i64 index = layout_index_from_ptr(pending_wrap_ptr, text.str, range.first); + lr_tb_align_rightward(&pos_vars, wrap_align_x); + lr_tb_write_ghost(&pos_vars, face, arena, &list, index, '\\'); -lr_tb_next_line(&pos_vars); + lr_tb_next_line(&pos_vars); #if 0 -f32 shift = layout_index_x_shift(app, &reflex, file, index, regular_indent); -lr_tb_advance_x_without_item(&pos_vars, shift); + f32 shift = layout_index_x_shift(app, &reflex, file, index, regular_indent); + lr_tb_advance_x_without_item(&pos_vars, shift); #endif -ptr = pending_wrap_ptr; -pending_wrap_accumulated_w = 0.f; -first_of_the_line = true; -goto start; -} -} + ptr = pending_wrap_ptr; + pending_wrap_accumulated_w = 0.f; + first_of_the_line = true; + goto start; + } + } -consuming_normal_whitespace: -for (; ptr < end_ptr; ptr += 1){ -if (!character_is_whitespace(*ptr)){ -u8 *new_wrap_ptr = ptr; + consuming_normal_whitespace: + for (; ptr < end_ptr; ptr += 1){ + if (!character_is_whitespace(*ptr)){ + u8 *new_wrap_ptr = ptr; -i64 index = layout_index_from_ptr(new_wrap_ptr, text.str, range.first); -Code_Index_Nest *new_wrap_nest = code_index_get_nest(file, index); -b32 invalid_wrap_x = false; -f32 new_wrap_x = layout_index_x_shift(app, &reflex, new_wrap_nest, index, regular_indent, &invalid_wrap_x); -if (invalid_wrap_x){ -new_wrap_x = max_f32; -} + i64 index = layout_index_from_ptr(new_wrap_ptr, text.str, range.first); + Code_Index_Nest *new_wrap_nest = code_index_get_nest(file, index); + b32 invalid_wrap_x = false; + f32 new_wrap_x = layout_index_x_shift(app, &reflex, new_wrap_nest, index, regular_indent, &invalid_wrap_x); + if (invalid_wrap_x){ + new_wrap_x = max_f32; + } -i32 new_wrap_paren_nest_count = 0; -for (Code_Index_Nest *nest = new_wrap_nest; - nest != 0; - nest = nest->parent){ -if (nest->kind == CodeIndexNest_Paren){ -new_wrap_paren_nest_count += 1; -} -} + i32 new_wrap_paren_nest_count = 0; + for (Code_Index_Nest *nest = new_wrap_nest; + nest != 0; + nest = nest->parent){ + if (nest->kind == CodeIndexNest_Paren){ + new_wrap_paren_nest_count += 1; + } + } -Token_Pair new_wrap_token_pair = layout_token_pair(tokens_ptr, index); + Token_Pair new_wrap_token_pair = layout_token_pair(tokens_ptr, index); -// TODO(allen): pull out the token scoring part and make it replacable for other -// language's token based wrap scoring needs. -i32 token_score = 0; -if (new_wrap_token_pair.a.kind == TokenBaseKind_Keyword){ -if (new_wrap_token_pair.b.kind == TokenBaseKind_ParentheticalOpen || - new_wrap_token_pair.b.kind == TokenBaseKind_Keyword){ -token_score -= 2; -} -} -token_score += layout_token_score_wrap_token(&new_wrap_token_pair, TokenCppKind_Eq); -token_score += layout_token_score_wrap_token(&new_wrap_token_pair, TokenCppKind_PlusEq); -token_score += layout_token_score_wrap_token(&new_wrap_token_pair, TokenCppKind_MinusEq); -token_score += layout_token_score_wrap_token(&new_wrap_token_pair, TokenCppKind_StarEq); -token_score += layout_token_score_wrap_token(&new_wrap_token_pair, TokenCppKind_DivEq); -token_score += layout_token_score_wrap_token(&new_wrap_token_pair, TokenCppKind_ModEq); -token_score += layout_token_score_wrap_token(&new_wrap_token_pair, TokenCppKind_LeftLeftEq); -token_score += layout_token_score_wrap_token(&new_wrap_token_pair, TokenCppKind_RightRightEq); -token_score += layout_token_score_wrap_token(&new_wrap_token_pair, TokenCppKind_Comma); -token_score += layout_token_score_wrap_token(&new_wrap_token_pair, TokenCppKind_AndAnd); -token_score += layout_token_score_wrap_token(&new_wrap_token_pair, TokenCppKind_OrOr); -token_score += layout_token_score_wrap_token(&new_wrap_token_pair, TokenCppKind_Ternary); -token_score += layout_token_score_wrap_token(&new_wrap_token_pair, TokenCppKind_Colon); -token_score += layout_token_score_wrap_token(&new_wrap_token_pair, TokenCppKind_Semicolon); + // TODO(allen): pull out the token scoring part and make it replacable for other + // language's token based wrap scoring needs. + i32 token_score = 0; + if (new_wrap_token_pair.a.kind == TokenBaseKind_Keyword){ + if (new_wrap_token_pair.b.kind == TokenBaseKind_ParentheticalOpen || + new_wrap_token_pair.b.kind == TokenBaseKind_Keyword){ + token_score -= 2; + } + } + token_score += layout_token_score_wrap_token(&new_wrap_token_pair, TokenCppKind_Eq); + token_score += layout_token_score_wrap_token(&new_wrap_token_pair, TokenCppKind_PlusEq); + token_score += layout_token_score_wrap_token(&new_wrap_token_pair, TokenCppKind_MinusEq); + token_score += layout_token_score_wrap_token(&new_wrap_token_pair, TokenCppKind_StarEq); + token_score += layout_token_score_wrap_token(&new_wrap_token_pair, TokenCppKind_DivEq); + token_score += layout_token_score_wrap_token(&new_wrap_token_pair, TokenCppKind_ModEq); + token_score += layout_token_score_wrap_token(&new_wrap_token_pair, TokenCppKind_LeftLeftEq); + token_score += layout_token_score_wrap_token(&new_wrap_token_pair, TokenCppKind_RightRightEq); + token_score += layout_token_score_wrap_token(&new_wrap_token_pair, TokenCppKind_Comma); + token_score += layout_token_score_wrap_token(&new_wrap_token_pair, TokenCppKind_AndAnd); + token_score += layout_token_score_wrap_token(&new_wrap_token_pair, TokenCppKind_OrOr); + token_score += layout_token_score_wrap_token(&new_wrap_token_pair, TokenCppKind_Ternary); + token_score += layout_token_score_wrap_token(&new_wrap_token_pair, TokenCppKind_Colon); + token_score += layout_token_score_wrap_token(&new_wrap_token_pair, TokenCppKind_Semicolon); -i32 new_wrap_token_score = token_score; + i32 new_wrap_token_score = token_score; -b32 new_wrap_ptr_is_better = false; -if (first_of_the_line){ -new_wrap_ptr_is_better = true; -} -else{ -if (new_wrap_token_score > pending_wrap_token_score){ -new_wrap_ptr_is_better = true; -} -else if (new_wrap_token_score == pending_wrap_token_score){ -f32 new_score = new_wrap_paren_nest_count*10.f + new_wrap_x; -f32 old_score = pending_wrap_paren_nest_count*10.f + pending_wrap_x + metrics.normal_advance*4.f + pending_wrap_accumulated_w*0.5f; + b32 new_wrap_ptr_is_better = false; + if (first_of_the_line){ + new_wrap_ptr_is_better = true; + } + else{ + if (new_wrap_token_score > pending_wrap_token_score){ + new_wrap_ptr_is_better = true; + } + else if (new_wrap_token_score == pending_wrap_token_score){ + f32 new_score = new_wrap_paren_nest_count*10.f + new_wrap_x; + f32 old_score = pending_wrap_paren_nest_count*10.f + pending_wrap_x + metrics.normal_advance*4.f + pending_wrap_accumulated_w*0.5f; -if (new_score < old_score){ -new_wrap_ptr_is_better = true; -} -} -} + if (new_score < old_score){ + new_wrap_ptr_is_better = true; + } + } + } -if (new_wrap_ptr_is_better){ -layout_index__emit_chunk(&pos_vars, face, arena, text.str, range.first, pending_wrap_ptr, new_wrap_ptr, &list); -first_of_the_line = false; + if (new_wrap_ptr_is_better){ + layout_index__emit_chunk(&pos_vars, face, arena, text.str, range.first, pending_wrap_ptr, new_wrap_ptr, &list); + first_of_the_line = false; -pending_wrap_ptr = new_wrap_ptr; -pending_wrap_paren_nest_count = new_wrap_paren_nest_count; -pending_wrap_x = layout_index_x_shift(app, &reflex, new_wrap_nest, index, regular_indent); -pending_wrap_paren_nest_count = new_wrap_paren_nest_count; -pending_wrap_token_score = new_wrap_token_score; -pending_wrap_accumulated_w = 0.f; -} + pending_wrap_ptr = new_wrap_ptr; + pending_wrap_paren_nest_count = new_wrap_paren_nest_count; + pending_wrap_x = layout_index_x_shift(app, &reflex, new_wrap_nest, index, regular_indent); + pending_wrap_paren_nest_count = new_wrap_paren_nest_count; + pending_wrap_token_score = new_wrap_token_score; + pending_wrap_accumulated_w = 0.f; + } -word_ptr = ptr; -goto consuming_non_whitespace; -} + word_ptr = ptr; + goto consuming_non_whitespace; + } -i64 index = layout_index_from_ptr(ptr, text.str, range.first); -switch (*ptr){ -default: -{ -newline_layout_consume_default(&newline_vars); -pending_wrap_accumulated_w += lr_tb_advance(&pos_vars, face, *ptr); -}break; + i64 index = layout_index_from_ptr(ptr, text.str, range.first); + switch (*ptr){ + default: + { + newline_layout_consume_default(&newline_vars); + pending_wrap_accumulated_w += lr_tb_advance(&pos_vars, face, *ptr); + }break; -case '\r': -{ -newline_layout_consume_CR(&newline_vars, index); -}break; + case '\r': + { + newline_layout_consume_CR(&newline_vars, index); + }break; -case '\n': -{ -layout_index__emit_chunk(&pos_vars, face, arena, text.str, range.first, pending_wrap_ptr, ptr, &list); -pending_wrap_ptr = ptr + 1; -pending_wrap_accumulated_w = 0.f; + case '\n': + { + layout_index__emit_chunk(&pos_vars, face, arena, text.str, range.first, pending_wrap_ptr, ptr, &list); + pending_wrap_ptr = ptr + 1; + pending_wrap_accumulated_w = 0.f; -u64 newline_index = newline_layout_consume_LF(&newline_vars, index); -lr_tb_write_blank(&pos_vars, face, arena, &list, newline_index); -lr_tb_next_line(&pos_vars); -first_of_the_line = true; -ptr += 1; -goto start; -}break; -} -} + u64 newline_index = newline_layout_consume_LF(&newline_vars, index); + lr_tb_write_blank(&pos_vars, face, arena, &list, newline_index); + lr_tb_next_line(&pos_vars); + first_of_the_line = true; + ptr += 1; + goto start; + }break; + } + } -finish: -if (newline_layout_consume_finish(&newline_vars)){ -layout_index__emit_chunk(&pos_vars, face, arena, text.str, range.first, pending_wrap_ptr, ptr, &list); -i64 index = layout_index_from_ptr(ptr, text.str, range.first); -lr_tb_write_blank(&pos_vars, face, arena, &list, index); -} -} + finish: + if (newline_layout_consume_finish(&newline_vars)){ + layout_index__emit_chunk(&pos_vars, face, arena, text.str, range.first, pending_wrap_ptr, ptr, &list); + i64 index = layout_index_from_ptr(ptr, text.str, range.first); + lr_tb_write_blank(&pos_vars, face, arena, &list, index); + } + } -layout_item_list_finish(&list, -pos_vars.line_to_text_shift); + layout_item_list_finish(&list, -pos_vars.line_to_text_shift); -return(list); + return(list); } function Layout_Item_List layout_virt_indent_index(Application_Links *app, Arena *arena, Buffer_ID buffer, Range_i64 range, Face_ID face, f32 width, Layout_Wrap_Kind kind){ -Layout_Item_List result = {}; + Layout_Item_List result = {}; -b32 enable_virtual_whitespace = def_get_config_b32(vars_save_string_lit("enable_virtual_whitespace")); -if (enable_virtual_whitespace){ -code_index_lock(); -Code_Index_File *file = code_index_get_file(buffer); -if (file != 0){ -result = layout_index__inner(app, arena, buffer, range, face, width, file, kind); -} -code_index_unlock(); -if (file == 0){ -result = layout_virt_indent_literal(app, arena, buffer, range, face, width, kind); -} -} -else{ -result = layout_basic(app, arena, buffer, range, face, width, kind); -} + b32 enable_virtual_whitespace = def_get_config_b32(vars_save_string_lit("enable_virtual_whitespace")); + if (enable_virtual_whitespace){ + code_index_lock(); + Code_Index_File *file = code_index_get_file(buffer); + if (file != 0){ + result = layout_index__inner(app, arena, buffer, range, face, width, file, kind); + } + code_index_unlock(); + if (file == 0){ + result = layout_virt_indent_literal(app, arena, buffer, range, face, width, kind); + } + } + else{ + result = layout_basic(app, arena, buffer, range, face, width, kind); + } -return(result); + return(result); } function Layout_Item_List layout_virt_indent_index_unwrapped(Application_Links *app, Arena *arena, Buffer_ID buffer, Range_i64 range, Face_ID face, f32 width){ -return(layout_virt_indent_index(app, arena, buffer, range, face, width, Layout_Unwrapped)); + return(layout_virt_indent_index(app, arena, buffer, range, face, width, Layout_Unwrapped)); } function Layout_Item_List layout_virt_indent_index_wrapped(Application_Links *app, Arena *arena, Buffer_ID buffer, Range_i64 range, Face_ID face, f32 width){ -return(layout_virt_indent_index(app, arena, buffer, range, face, width, Layout_Wrapped)); + return(layout_virt_indent_index(app, arena, buffer, range, face, width, Layout_Wrapped)); } function Layout_Item_List layout_virt_indent_index_generic(Application_Links *app, Arena *arena, Buffer_ID buffer, Range_i64 range, Face_ID face, f32 width){ -Managed_Scope scope = buffer_get_managed_scope(app, buffer); -b32 *wrap_lines_ptr = scope_attachment(app, scope, buffer_wrap_lines, b32); -b32 wrap_lines = (wrap_lines_ptr != 0 && *wrap_lines_ptr); -return(layout_virt_indent_index(app, arena, buffer, range, face, width, wrap_lines?Layout_Wrapped:Layout_Unwrapped)); + Managed_Scope scope = buffer_get_managed_scope(app, buffer); + b32 *wrap_lines_ptr = scope_attachment(app, scope, buffer_wrap_lines, b32); + b32 wrap_lines = (wrap_lines_ptr != 0 && *wrap_lines_ptr); + return(layout_virt_indent_index(app, arena, buffer, range, face, width, wrap_lines?Layout_Wrapped:Layout_Unwrapped)); } CUSTOM_COMMAND_SIG(toggle_virtual_whitespace) CUSTOM_DOC("Toggles virtual whitespace for all files.") { -String_ID key = vars_save_string_lit("enable_virtual_whitespace"); -b32 enable_virtual_whitespace = def_get_config_b32(key); -def_set_config_b32(key, !enable_virtual_whitespace); + String_ID key = vars_save_string_lit("enable_virtual_whitespace"); + b32 enable_virtual_whitespace = def_get_config_b32(key); + def_set_config_b32(key, !enable_virtual_whitespace); } // BOTTOM