From ad5b203b57ab9430b5b7e9c80e5061ee32c6cec1 Mon Sep 17 00:00:00 2001 From: Allen Webster Date: Mon, 24 Oct 2016 20:26:52 -0400 Subject: [PATCH] preprocessor code wrapping rule --- 4coder_API.html | 4 +-- 4cpp_lexer_types.h | 4 +-- 4ed.cpp | 2 +- 4ed_file_view.cpp | 83 +++++++++++++++++++++++++++++----------------- TODO.txt | 5 +-- 5 files changed, 59 insertions(+), 39 deletions(-) diff --git a/4coder_API.html b/4coder_API.html index 1c51b70e..3ec9d69d 100644 --- a/4coder_API.html +++ b/4coder_API.html @@ -408,9 +408,7 @@ than the current size of the array the operation is ignored.
See Also
cpp_make_token_array

§5.4.19: cpp_lex_file

void cpp_lex_file(
char *data,
int32_t size,
Cpp_Token_Array *token_array_out
)
Parameters
data
The file data to be lexed in a single contiguous block.
size
The number of bytes in data.
token_array_out
The token array where the output tokens will be pushed. This token array must be previously allocated with cpp_make_token_array
Description
Lexes an entire file and manages the interaction with the lexer system so that it is quick and convenient to lex files.

-

Cpp_Token_Array lex_file(char *file_name){
    File_Data file = read_whole_file(file_name);
    
    // This array will be automatically grown if it runs
    // out of memory.
    Cpp_Token_Array array = cpp_make_token_array(100);
    
    cpp_lex_file(file.data, file.size, &array);
    
    return(array);
}
See Also
cpp_make_token_array

§5.5 Lexer Type Descriptions

§5.5.1: Cpp_Token_Type

enum Cpp_Token_Type;
Description
A Cpp_Token_Type classifies a token to make parsing easier. Some types are not -actually output by the lexer, but exist because parsers will also make use of token -types in their own output.

Values
CPP_TOKEN_JUNK = 0
CPP_TOKEN_COMMENT = 1
CPP_PP_INCLUDE = 2
CPP_PP_DEFINE = 3
CPP_PP_UNDEF = 4
CPP_PP_IF = 5
CPP_PP_IFDEF = 6
CPP_PP_IFNDEF = 7
CPP_PP_ELSE = 8
CPP_PP_ELIF = 9
CPP_PP_ENDIF = 10
CPP_PP_ERROR = 11
CPP_PP_IMPORT = 12
CPP_PP_USING = 13
CPP_PP_LINE = 14
CPP_PP_PRAGMA = 15
CPP_PP_STRINGIFY = 16
CPP_PP_CONCAT = 17
CPP_PP_UNKNOWN = 18
CPP_PP_DEFINED = 19
CPP_PP_INCLUDE_FILE = 20
CPP_PP_ERROR_MESSAGE = 21
CPP_TOKEN_KEY_TYPE = 22
CPP_TOKEN_KEY_MODIFIER = 23
CPP_TOKEN_KEY_QUALIFIER = 24
CPP_TOKEN_KEY_OPERATOR = 25
This type is not stored in token output from the lexer.

CPP_TOKEN_KEY_CONTROL_FLOW = 26
CPP_TOKEN_KEY_CAST = 27
CPP_TOKEN_KEY_TYPE_DECLARATION = 28
CPP_TOKEN_KEY_ACCESS = 29
CPP_TOKEN_KEY_LINKAGE = 30
CPP_TOKEN_KEY_OTHER = 31
CPP_TOKEN_IDENTIFIER = 32
CPP_TOKEN_INTEGER_CONSTANT = 33
CPP_TOKEN_CHARACTER_CONSTANT = 34
CPP_TOKEN_FLOATING_CONSTANT = 35
CPP_TOKEN_STRING_CONSTANT = 36
CPP_TOKEN_BOOLEAN_CONSTANT = 37
CPP_TOKEN_STATIC_ASSERT = 38
CPP_TOKEN_BRACKET_OPEN = 39
CPP_TOKEN_BRACKET_CLOSE = 40
CPP_TOKEN_PARENTHESE_OPEN = 41
CPP_TOKEN_PARENTHESE_CLOSE = 42
CPP_TOKEN_BRACE_OPEN = 43
CPP_TOKEN_BRACE_CLOSE = 44
CPP_TOKEN_SEMICOLON = 45
CPP_TOKEN_ELLIPSIS = 46
CPP_TOKEN_STAR = 47
This is an 'ambiguous' token type because it requires +

Cpp_Token_Array lex_file(char *file_name){
    File_Data file = read_whole_file(file_name);
    
    // This array will be automatically grown if it runs
    // out of memory.
    Cpp_Token_Array array = cpp_make_token_array(100);
    
    cpp_lex_file(file.data, file.size, &array);
    
    return(array);
}
See Also

§5.5 Lexer Type Descriptions

§5.5.1: Cpp_Token_Type

enum Cpp_Token_Type;
Description
A Cpp_Token_Type classifies a token to make parsing easier. Some types are not actually output by the lexer, but exist because parsers will also make use of token types in their own output.

Values
CPP_TOKEN_JUNK = 0
CPP_TOKEN_COMMENT = 1
CPP_PP_INCLUDE = 2
CPP_PP_DEFINE = 3
CPP_PP_UNDEF = 4
CPP_PP_IF = 5
CPP_PP_IFDEF = 6
CPP_PP_IFNDEF = 7
CPP_PP_ELSE = 8
CPP_PP_ELIF = 9
CPP_PP_ENDIF = 10
CPP_PP_ERROR = 11
CPP_PP_IMPORT = 12
CPP_PP_USING = 13
CPP_PP_LINE = 14
CPP_PP_PRAGMA = 15
CPP_PP_STRINGIFY = 16
CPP_PP_CONCAT = 17
CPP_PP_UNKNOWN = 18
CPP_PP_DEFINED = 19
CPP_PP_INCLUDE_FILE = 20
CPP_PP_ERROR_MESSAGE = 21
CPP_TOKEN_KEY_TYPE = 22
CPP_TOKEN_KEY_MODIFIER = 23
CPP_TOKEN_KEY_QUALIFIER = 24
CPP_TOKEN_KEY_OPERATOR = 25
This type is not stored in token output from the lexer.

CPP_TOKEN_KEY_CONTROL_FLOW = 26
CPP_TOKEN_KEY_CAST = 27
CPP_TOKEN_KEY_TYPE_DECLARATION = 28
CPP_TOKEN_KEY_ACCESS = 29
CPP_TOKEN_KEY_LINKAGE = 30
CPP_TOKEN_KEY_OTHER = 31
CPP_TOKEN_IDENTIFIER = 32
CPP_TOKEN_INTEGER_CONSTANT = 33
CPP_TOKEN_CHARACTER_CONSTANT = 34
CPP_TOKEN_FLOATING_CONSTANT = 35
CPP_TOKEN_STRING_CONSTANT = 36
CPP_TOKEN_BOOLEAN_CONSTANT = 37
CPP_TOKEN_STATIC_ASSERT = 38
CPP_TOKEN_BRACKET_OPEN = 39
CPP_TOKEN_BRACKET_CLOSE = 40
CPP_TOKEN_PARENTHESE_OPEN = 41
CPP_TOKEN_PARENTHESE_CLOSE = 42
CPP_TOKEN_BRACE_OPEN = 43
CPP_TOKEN_BRACE_CLOSE = 44
CPP_TOKEN_SEMICOLON = 45
CPP_TOKEN_ELLIPSIS = 46
CPP_TOKEN_STAR = 47
This is an 'ambiguous' token type because it requires parsing to determine the full nature of the token.

CPP_TOKEN_AMPERSAND = 48
This is an 'ambiguous' token type because it requires parsing to determine the full nature of the token.

CPP_TOKEN_TILDE = 49
This is an 'ambiguous' token type because it requires parsing to determine the full nature of the token.

CPP_TOKEN_PLUS = 50
This is an 'ambiguous' token type because it requires diff --git a/4cpp_lexer_types.h b/4cpp_lexer_types.h index 30ba13f9..2abf182e 100644 --- a/4cpp_lexer_types.h +++ b/4cpp_lexer_types.h @@ -16,9 +16,7 @@ #define struct_internal struct #endif -/* DOC(A Cpp_Token_Type classifies a token to make parsing easier. Some types are not -actually output by the lexer, but exist because parsers will also make use of token -types in their own output.) */ +/* DOC(A Cpp_Token_Type classifies a token to make parsing easier. Some types are not actually output by the lexer, but exist because parsers will also make use of token types in their own output.) */ ENUM(uint32_t, Cpp_Token_Type){ CPP_TOKEN_JUNK = 0, diff --git a/4ed.cpp b/4ed.cpp index 8e61daa4..7ad73be3 100644 --- a/4ed.cpp +++ b/4ed.cpp @@ -12,7 +12,7 @@ // App Structs #define DEFAULT_DISPLAY_WIDTH 672 -#define DEFAULT_MINIMUM_BASE_DISPLAY_WIDTH 450 +#define DEFAULT_MINIMUM_BASE_DISPLAY_WIDTH 550 typedef enum App_State{ APP_STATE_EDIT, diff --git a/4ed_file_view.cpp b/4ed_file_view.cpp index b58c4204..4a359957 100644 --- a/4ed_file_view.cpp +++ b/4ed_file_view.cpp @@ -975,15 +975,23 @@ file_allocate_wrap_positions_as_needed(System_Functions *system, General_Memory file_allocate_metadata_as_needed(system, general, &file->state.buffer, (void**)&file->state.wrap_positions, &file->state.wrap_position_max, min_amount, sizeof(f32)); } +struct Code_Wrap_X{ + f32 base_x; + f32 paren_nesting[32]; + i32 paren_safe_top; + i32 paren_top; +}; +globalvar Code_Wrap_X null_wrap_x = {0}; + struct Code_Wrap_State{ Cpp_Token_Array token_array; Cpp_Token *token_ptr; Cpp_Token *end_token; - f32 base_x; - f32 paren_nesting[32]; - i32 paren_safe_top; - i32 paren_top; + Code_Wrap_X wrap_x; + + b32 in_pp_body; + Code_Wrap_X plane_wrap_x; i32 *line_starts; i32 line_index; @@ -1028,8 +1036,8 @@ wrap_state_set_i(Code_Wrap_State *state, i32 i){ internal void wrap_state_set_top(Code_Wrap_State *state, f32 line_shift){ - if (state->paren_nesting[state->paren_safe_top] > line_shift){ - state->paren_nesting[state->paren_safe_top] = line_shift; + if (state->wrap_x.paren_nesting[state->wrap_x.paren_safe_top] > line_shift){ + state->wrap_x.paren_nesting[state->wrap_x.paren_safe_top] = line_shift; } } @@ -1056,9 +1064,24 @@ wrap_state_consume_token(Code_Wrap_State *state, i32 fixed_end_point){ state->consume_newline = 0; } + if (state->in_pp_body){ + if (!(state->token_ptr->flags & CPP_TFLAG_PP_BODY)){ + state->in_pp_body = 0; + state->wrap_x = state->plane_wrap_x; + } + } + + if (!state->in_pp_body){ + if (state->token_ptr->flags & CPP_TFLAG_PP_DIRECTIVE){ + state->in_pp_body = 1; + state->plane_wrap_x = state->wrap_x; + state->wrap_x = null_wrap_x; + } + } + b32 skipping_whitespace = 0; if (i >= state->next_line_start){ - state->x = state->paren_nesting[state->paren_safe_top]; + state->x = state->wrap_x.paren_nesting[state->wrap_x.paren_safe_top]; skipping_whitespace = 1; } @@ -1128,42 +1151,42 @@ wrap_state_consume_token(Code_Wrap_State *state, i32 fixed_end_point){ switch (state->token_ptr->type){ case CPP_TOKEN_BRACE_OPEN: { - state->paren_nesting[state->paren_safe_top] += state->tab_indent_amount; + state->wrap_x.paren_nesting[state->wrap_x.paren_safe_top] += state->tab_indent_amount; }break; case CPP_TOKEN_BRACE_CLOSE: { - state->paren_nesting[state->paren_safe_top] -= state->tab_indent_amount; + state->wrap_x.paren_nesting[state->wrap_x.paren_safe_top] -= state->tab_indent_amount; }break; case CPP_TOKEN_PARENTHESE_OPEN: case CPP_TOKEN_BRACKET_OPEN: { - ++state->paren_top; + ++state->wrap_x.paren_top; - i32 top = state->paren_top; - if (top >= ArrayCount(state->paren_nesting)){ - top = ArrayCount(state->paren_nesting) - 1; + i32 top = state->wrap_x.paren_top; + if (top >= ArrayCount(state->wrap_x.paren_nesting)){ + top = ArrayCount(state->wrap_x.paren_nesting) - 1; } - state->paren_safe_top = top; + state->wrap_x.paren_safe_top = top; - state->paren_nesting[top] = state->x; + state->wrap_x.paren_nesting[top] = state->x; }break; case CPP_TOKEN_PARENTHESE_CLOSE: case CPP_TOKEN_BRACKET_CLOSE: { - --state->paren_top; + --state->wrap_x.paren_top; - if (state->paren_top < 0){ - state->paren_top = 0; + if (state->wrap_x.paren_top < 0){ + state->wrap_x.paren_top = 0; } - i32 top = state->paren_top; - if (top >= ArrayCount(state->paren_nesting)){ - top = ArrayCount(state->paren_nesting) - 1; + i32 top = state->wrap_x.paren_top; + if (top >= ArrayCount(state->wrap_x.paren_nesting)){ + top = ArrayCount(state->wrap_x.paren_nesting) - 1; } - state->paren_safe_top = top; + state->wrap_x.paren_safe_top = top; }break; } @@ -1332,20 +1355,20 @@ stickieness_guess(Cpp_Token_Type type, Cpp_Token_Type other_type, u16 flags, u16 internal f32 get_current_shift(Code_Wrap_State *wrap_state, i32 next_line_start, b32 *adjust_top_to_this){ - f32 current_shift = wrap_state->paren_nesting[wrap_state->paren_safe_top]; + f32 current_shift = wrap_state->wrap_x.paren_nesting[wrap_state->wrap_x.paren_safe_top]; Assert(adjust_top_to_this != 0); if (wrap_state->token_ptr > wrap_state->token_array.tokens){ Cpp_Token prev_token = *(wrap_state->token_ptr-1); - if (wrap_state->paren_safe_top != 0 && prev_token.type == CPP_TOKEN_PARENTHESE_OPEN){ - current_shift = wrap_state->paren_nesting[wrap_state->paren_safe_top-1] + wrap_state->tab_indent_amount; + if (wrap_state->wrap_x.paren_safe_top != 0 && prev_token.type == CPP_TOKEN_PARENTHESE_OPEN){ + current_shift = wrap_state->wrap_x.paren_nesting[wrap_state->wrap_x.paren_safe_top-1] + wrap_state->tab_indent_amount; *adjust_top_to_this = 1; } f32 statement_continuation_indent = 0.f; - if (current_shift != 0.f && wrap_state->paren_safe_top == 0){ + if (current_shift != 0.f && wrap_state->wrap_x.paren_safe_top == 0){ if (!(prev_token.flags & CPP_TFLAG_PP_BODY) && !(prev_token.flags & CPP_TFLAG_PP_DIRECTIVE)){ switch (prev_token.type){ @@ -1375,7 +1398,7 @@ get_current_shift(Code_Wrap_State *wrap_state, i32 next_line_start, b32 *adjust_ switch (wrap_state->token_ptr->type){ case CPP_TOKEN_BRACE_CLOSE: { - if (wrap_state->paren_safe_top == 0){ + if (wrap_state->wrap_x.paren_safe_top == 0){ current_shift -= wrap_state->tab_indent_amount; } }break; @@ -1526,7 +1549,7 @@ file_measure_wraps(System_Functions *system, Models *models, Editing_File *file, Code_Wrap_State original_wrap_state = wrap_state; i32 next_line_start = params.buffer->line_starts[stop.line_index+1]; - f32 base_adjusted_width = wrap_state.base_x + minimum_base_width; + f32 base_adjusted_width = wrap_state.wrap_x.base_x + minimum_base_width; if (minimum_base_width != 0 && current_width < base_adjusted_width){ current_width = base_adjusted_width; @@ -1548,7 +1571,7 @@ file_measure_wraps(System_Functions *system, Models *models, Editing_File *file, wrap_indent_marks[real_count].line_shift = clamp_bottom(0.f, current_shift); ++real_count; - wrap_state.base_x = wrap_state.paren_nesting[0]; + wrap_state.wrap_x.base_x = wrap_state.wrap_x.paren_nesting[0]; for (; wrap_state.token_ptr < wrap_state.end_token; ){ Code_Wrap_Step step = {0}; @@ -1696,7 +1719,7 @@ file_measure_wraps(System_Functions *system, Models *models, Editing_File *file, } wrappable_score = 64*50; - wrappable_score += 101 - general_stickieness - wrap_state.paren_safe_top*80; + wrappable_score += 101 - general_stickieness - wrap_state.wrap_x.paren_safe_top*80; potential_marks[potential_count].wrap_position = wrap_position; potential_marks[potential_count].line_shift = current_shift; diff --git a/TODO.txt b/TODO.txt index d957a6f6..6c3b6694 100644 --- a/TODO.txt +++ b/TODO.txt @@ -176,9 +176,10 @@ ; [X] smarter wrap rule ; [X] handle unclosed statements ; [X] wrapped line indication +; [X] additional width for nesting? +; [X] handle comments +; [] solve the comment lead whitespace problem ; [] special indent rules in preprocessor body -; [] handle comments -; [] additional width for nesting? ; [] fix issues when relexing happens in parallel ; [] remeasure version of measure_wraps