lots of progress on 4.0.19

This commit is contained in:
Allen Webster 2017-04-15 17:47:23 -04:00
parent e5ec7f8488
commit bc4c866cf0
27 changed files with 1337 additions and 543 deletions

View File

@ -14,6 +14,7 @@ struct Application_Links;
#define BUFFER_COMPUTE_CURSOR_SIG(n) bool32 n(Application_Links *app, Buffer_Summary *buffer, Buffer_Seek seek, Partial_Cursor *cursor_out)
#define BUFFER_BATCH_EDIT_SIG(n) bool32 n(Application_Links *app, Buffer_Summary *buffer, char *str, int32_t str_len, Buffer_Edit *edits, int32_t edit_count, Buffer_Batch_Edit_Type type)
#define BUFFER_ADD_MARKERS_SIG(n) Marker_Handle n(Application_Links *app, Buffer_Summary *buffer, uint32_t marker_count)
#define GET_BUFFER_BY_MARKER_HANDLE_SIG(n) Buffer_Summary n(Application_Links *app, Marker_Handle marker, Access_Flag access)
#define BUFFER_SET_MARKERS_SIG(n) bool32 n(Application_Links *app, Buffer_Summary *buffer, Marker_Handle marker, uint32_t first_marker_index, uint32_t marker_count, Marker *source_markers)
#define BUFFER_GET_MARKERS_SIG(n) bool32 n(Application_Links *app, Buffer_Summary *buffer, Marker_Handle marker, uint32_t first_marker_index, uint32_t marker_count, Marker *markers_out)
#define BUFFER_REMOVE_MARKERS_SIG(n) bool32 n(Application_Links *app, Buffer_Summary *buffer, Marker_Handle marker)
@ -59,7 +60,7 @@ struct Application_Links;
#define DIRECTORY_GET_HOT_SIG(n) int32_t n(Application_Links *app, char *out, int32_t capacity)
#define GET_FILE_LIST_SIG(n) File_List n(Application_Links *app, char *dir, int32_t len)
#define FREE_FILE_LIST_SIG(n) void n(Application_Links *app, File_List list)
#define SET_GUI_UP_DOWN_KEYS_SIG(n) void n(Application_Links *app, int16_t up_key, int16_t down_key)
#define SET_GUI_UP_DOWN_KEYS_SIG(n) void n(Application_Links *app, Key_Code up_key, Key_Modifier up_key_modifier, Key_Code down_key, Key_Modifier down_key_modifier)
#define MEMORY_ALLOCATE_SIG(n) void* n(Application_Links *app, int32_t size)
#define MEMORY_SET_PROTECTION_SIG(n) bool32 n(Application_Links *app, void *ptr, int32_t size, Memory_Protect_Flags flags)
#define MEMORY_FREE_SIG(n) void n(Application_Links *app, void *ptr, int32_t size)
@ -85,6 +86,7 @@ typedef BUFFER_REPLACE_RANGE_SIG(Buffer_Replace_Range_Function);
typedef BUFFER_COMPUTE_CURSOR_SIG(Buffer_Compute_Cursor_Function);
typedef BUFFER_BATCH_EDIT_SIG(Buffer_Batch_Edit_Function);
typedef BUFFER_ADD_MARKERS_SIG(Buffer_Add_Markers_Function);
typedef GET_BUFFER_BY_MARKER_HANDLE_SIG(Get_Buffer_By_Marker_Handle_Function);
typedef BUFFER_SET_MARKERS_SIG(Buffer_Set_Markers_Function);
typedef BUFFER_GET_MARKERS_SIG(Buffer_Get_Markers_Function);
typedef BUFFER_REMOVE_MARKERS_SIG(Buffer_Remove_Markers_Function);
@ -158,6 +160,7 @@ Buffer_Replace_Range_Function *buffer_replace_range;
Buffer_Compute_Cursor_Function *buffer_compute_cursor;
Buffer_Batch_Edit_Function *buffer_batch_edit;
Buffer_Add_Markers_Function *buffer_add_markers;
Get_Buffer_By_Marker_Handle_Function *get_buffer_by_marker_handle;
Buffer_Set_Markers_Function *buffer_set_markers;
Buffer_Get_Markers_Function *buffer_get_markers;
Buffer_Remove_Markers_Function *buffer_remove_markers;
@ -230,6 +233,7 @@ Buffer_Replace_Range_Function *buffer_replace_range_;
Buffer_Compute_Cursor_Function *buffer_compute_cursor_;
Buffer_Batch_Edit_Function *buffer_batch_edit_;
Buffer_Add_Markers_Function *buffer_add_markers_;
Get_Buffer_By_Marker_Handle_Function *get_buffer_by_marker_handle_;
Buffer_Set_Markers_Function *buffer_set_markers_;
Buffer_Get_Markers_Function *buffer_get_markers_;
Buffer_Remove_Markers_Function *buffer_remove_markers_;
@ -310,6 +314,7 @@ app_links->buffer_replace_range_ = Buffer_Replace_Range;\
app_links->buffer_compute_cursor_ = Buffer_Compute_Cursor;\
app_links->buffer_batch_edit_ = Buffer_Batch_Edit;\
app_links->buffer_add_markers_ = Buffer_Add_Markers;\
app_links->get_buffer_by_marker_handle_ = Get_Buffer_By_Marker_Handle;\
app_links->buffer_set_markers_ = Buffer_Set_Markers;\
app_links->buffer_get_markers_ = Buffer_Get_Markers;\
app_links->buffer_remove_markers_ = Buffer_Remove_Markers;\
@ -382,6 +387,7 @@ static inline bool32 buffer_replace_range(Application_Links *app, Buffer_Summary
static inline bool32 buffer_compute_cursor(Application_Links *app, Buffer_Summary *buffer, Buffer_Seek seek, Partial_Cursor *cursor_out){return(app->buffer_compute_cursor(app, buffer, seek, cursor_out));}
static inline bool32 buffer_batch_edit(Application_Links *app, Buffer_Summary *buffer, char *str, int32_t str_len, Buffer_Edit *edits, int32_t edit_count, Buffer_Batch_Edit_Type type){return(app->buffer_batch_edit(app, buffer, str, str_len, edits, edit_count, type));}
static inline Marker_Handle buffer_add_markers(Application_Links *app, Buffer_Summary *buffer, uint32_t marker_count){return(app->buffer_add_markers(app, buffer, marker_count));}
static inline Buffer_Summary get_buffer_by_marker_handle(Application_Links *app, Marker_Handle marker, Access_Flag access){return(app->get_buffer_by_marker_handle(app, marker, access));}
static inline bool32 buffer_set_markers(Application_Links *app, Buffer_Summary *buffer, Marker_Handle marker, uint32_t first_marker_index, uint32_t marker_count, Marker *source_markers){return(app->buffer_set_markers(app, buffer, marker, first_marker_index, marker_count, source_markers));}
static inline bool32 buffer_get_markers(Application_Links *app, Buffer_Summary *buffer, Marker_Handle marker, uint32_t first_marker_index, uint32_t marker_count, Marker *markers_out){return(app->buffer_get_markers(app, buffer, marker, first_marker_index, marker_count, markers_out));}
static inline bool32 buffer_remove_markers(Application_Links *app, Buffer_Summary *buffer, Marker_Handle marker){return(app->buffer_remove_markers(app, buffer, marker));}
@ -427,7 +433,7 @@ static inline void get_theme_colors(Application_Links *app, Theme_Color *colors,
static inline int32_t directory_get_hot(Application_Links *app, char *out, int32_t capacity){return(app->directory_get_hot(app, out, capacity));}
static inline File_List get_file_list(Application_Links *app, char *dir, int32_t len){return(app->get_file_list(app, dir, len));}
static inline void free_file_list(Application_Links *app, File_List list){(app->free_file_list(app, list));}
static inline void set_gui_up_down_keys(Application_Links *app, int16_t up_key, int16_t down_key){(app->set_gui_up_down_keys(app, up_key, down_key));}
static inline void set_gui_up_down_keys(Application_Links *app, Key_Code up_key, Key_Modifier up_key_modifier, Key_Code down_key, Key_Modifier down_key_modifier){(app->set_gui_up_down_keys(app, up_key, up_key_modifier, down_key, down_key_modifier));}
static inline void* memory_allocate(Application_Links *app, int32_t size){return(app->memory_allocate(app, size));}
static inline bool32 memory_set_protection(Application_Links *app, void *ptr, int32_t size, Memory_Protect_Flags flags){return(app->memory_set_protection(app, ptr, size, flags));}
static inline void memory_free(Application_Links *app, void *ptr, int32_t size){(app->memory_free(app, ptr, size));}
@ -454,6 +460,7 @@ static inline bool32 buffer_replace_range(Application_Links *app, Buffer_Summary
static inline bool32 buffer_compute_cursor(Application_Links *app, Buffer_Summary *buffer, Buffer_Seek seek, Partial_Cursor *cursor_out){return(app->buffer_compute_cursor_(app, buffer, seek, cursor_out));}
static inline bool32 buffer_batch_edit(Application_Links *app, Buffer_Summary *buffer, char *str, int32_t str_len, Buffer_Edit *edits, int32_t edit_count, Buffer_Batch_Edit_Type type){return(app->buffer_batch_edit_(app, buffer, str, str_len, edits, edit_count, type));}
static inline Marker_Handle buffer_add_markers(Application_Links *app, Buffer_Summary *buffer, uint32_t marker_count){return(app->buffer_add_markers_(app, buffer, marker_count));}
static inline Buffer_Summary get_buffer_by_marker_handle(Application_Links *app, Marker_Handle marker, Access_Flag access){return(app->get_buffer_by_marker_handle_(app, marker, access));}
static inline bool32 buffer_set_markers(Application_Links *app, Buffer_Summary *buffer, Marker_Handle marker, uint32_t first_marker_index, uint32_t marker_count, Marker *source_markers){return(app->buffer_set_markers_(app, buffer, marker, first_marker_index, marker_count, source_markers));}
static inline bool32 buffer_get_markers(Application_Links *app, Buffer_Summary *buffer, Marker_Handle marker, uint32_t first_marker_index, uint32_t marker_count, Marker *markers_out){return(app->buffer_get_markers_(app, buffer, marker, first_marker_index, marker_count, markers_out));}
static inline bool32 buffer_remove_markers(Application_Links *app, Buffer_Summary *buffer, Marker_Handle marker){return(app->buffer_remove_markers_(app, buffer, marker));}
@ -499,7 +506,7 @@ static inline void get_theme_colors(Application_Links *app, Theme_Color *colors,
static inline int32_t directory_get_hot(Application_Links *app, char *out, int32_t capacity){return(app->directory_get_hot_(app, out, capacity));}
static inline File_List get_file_list(Application_Links *app, char *dir, int32_t len){return(app->get_file_list_(app, dir, len));}
static inline void free_file_list(Application_Links *app, File_List list){(app->free_file_list_(app, list));}
static inline void set_gui_up_down_keys(Application_Links *app, int16_t up_key, int16_t down_key){(app->set_gui_up_down_keys_(app, up_key, down_key));}
static inline void set_gui_up_down_keys(Application_Links *app, Key_Code up_key, Key_Modifier up_key_modifier, Key_Code down_key, Key_Modifier down_key_modifier){(app->set_gui_up_down_keys_(app, up_key, up_key_modifier, down_key, down_key_modifier));}
static inline void* memory_allocate(Application_Links *app, int32_t size){return(app->memory_allocate_(app, size));}
static inline bool32 memory_set_protection(Application_Links *app, void *ptr, int32_t size, Memory_Protect_Flags flags){return(app->memory_set_protection_(app, ptr, size, flags));}
static inline void memory_free(Application_Links *app, void *ptr, int32_t size){(app->memory_free_(app, ptr, size));}

View File

@ -27,8 +27,8 @@ TYPEDEF int32_t Buffer_ID;
/* DOC(View_ID is used to name a 4coder view. Each view has a unique id in the interval [1,16].) */
TYPEDEF int32_t View_ID;
/* DOC(A Key_Modifier acts as an index for specifying modifiers in arrays.) */
ENUM(int32_t, Key_Modifier){
/* DOC(A Key_Modifier_Index acts as an index for specifying modifiers in arrays.) */
ENUM(int32_t, Key_Modifier_Index){
MDFR_SHIFT_INDEX,
MDFR_CONTROL_INDEX,
MDFR_ALT_INDEX,
@ -145,6 +145,9 @@ ENUM(int32_t, Buffer_Setting_ID){
from with the buffer.) */
BufferSetting_Lex,
/* DOC(The BufferSetting_LexWithoutStrings tells the system to treat string and character marks as identifiers instead of strings. This settings does nothing if the buffer does not have lexing turned on.) */
BufferSetting_LexWithoutStrings,
/* DOC(The BufferSetting_WrapLine setting is used to determine whether a buffer prefers
to be viewed with wrapped lines, individual views can be set to override this value after
being tied to the buffer.) */
@ -340,6 +343,10 @@ ENUM(int32_t, View_Split_Position){
/* DOC(Key_Code is the alias for key codes including raw codes and codes translated to textual input that takes modifiers into account.) */
TYPEDEF uint32_t Key_Code;
/* DOC(Key_Modifier is the alias for flags that represent keyboard modifiers, ctrl, alt, shift, etc.)
DOC_SEE(Key_Modifier_Flag) */
TYPEDEF uint8_t Key_Modifier;
/* DOC(Key_Event_Data describes a key event, including the translation to a character, the translation to a character ignoring the state of caps lock, and an array of all the modifiers that were pressed at the time of the event.) */
STRUCT Key_Event_Data{
/* DOC(This field is the raw keycode which is always non-zero in valid key events.) */
@ -351,11 +358,11 @@ STRUCT Key_Event_Data{
/* DOC(This field is like the field character, except that the state of caps lock is ignored in the translation.) */
Key_Code character_no_caps_lock;
/* DOC(This field is an array indicating the state of modifiers at the time of the key press. The array is indexed using the values of Key_Modifier. 1 indicates that the corresponding modifier was held, and a 0 indicates that it was not held.)
/* DOC(This field is an array indicating the state of modifiers at the time of the key press. The array is indexed using the values of Key_Modifier_Index. 1 indicates that the corresponding modifier was held, and a 0 indicates that it was not held.)
DOC_SEE(Key_Modifier)
*/
char modifiers[MDFR_INDEX_COUNT];
int8_t modifiers[MDFR_INDEX_COUNT];
};
// TODO(allen): GLOBAL_VAR meta parsing

View File

@ -1,6 +1,6 @@
#define MAJOR 4
#define MINOR 0
#define PATCH 18
#define PATCH 19
// string
#define VN__(a,b,c) #a"."#b"."#c

View File

@ -26,11 +26,7 @@ CUSTOM_COMMAND_SIG(write_character){
User_Input in = get_command_input(app);
uint8_t character[4];
uint32_t length = 0;
if (in.type == UserInputKey){
u32_to_utf8_unchecked(in.key.character, character, &length);
}
uint32_t length = to_writable_character(in, character);
if (length != 0){
Buffer_Summary buffer = get_buffer(app, view.buffer_id, access);
int32_t pos = view.cursor.pos;
@ -630,26 +626,26 @@ isearch(Application_Links *app, int32_t start_reversed, String query_init){
bool32 backspace = false;
if (!first_step){
in = get_user_input(app, EventOnAnyKey, EventOnEsc | EventOnButton);
//in = get_user_input(app, EventOnAnyKey, EventOnEsc | EventOnButton);
in = get_user_input(app, EventOnAnyKey, EventOnEsc);
if (in.abort) break;
// NOTE(allen): If we're getting mouse events here it's a 4coder bug, because we only asked to intercept key events.
Assert(in.type == UserInputKey);
char character = to_writable_char(in.key.character);
uint8_t character[4];
uint32_t length = to_writable_character(in, character);
bool32 made_change = false;
if (in.key.keycode == '\n' || in.key.keycode == '\t'){
break;
}
else if (character && key_is_unmodified(&in.key)){
append_s_char(&bar.string, character);
else if (length != 0 && key_is_unmodified(&in.key)){
append_ss(&bar.string, make_string(character, length));
made_change = true;
}
else if (in.key.keycode == key_back){
if (bar.string.size > 0){
--bar.string.size;
made_change = true;
}
made_change = backspace_utf8(&bar.string);
backspace = true;
}

View File

@ -1,6 +1,5 @@
/*
4coder_default_framework.cpp - Sets up the basics of the framework that is used
for default 4coder behaviour.
4coder_default_framework.cpp - Sets up the basics of the framework that is used for default 4coder behaviour.
TYPE: 'internal-for-default-system'
*/
@ -291,11 +290,11 @@ get_current_project_extensions(int32_t *extension_count_out){
// Location Jumping State
//
typedef struct ID_Based_Jump_Location{
struct ID_Based_Jump_Location{
int32_t buffer_id;
int32_t line;
int32_t column;
} ID_Based_Jump_Location;
};
static ID_Based_Jump_Location null_location = {0};
static ID_Based_Jump_Location prev_location = {0};
@ -724,7 +723,7 @@ process_config_file(Application_Links *app){
array.max_count = (1 << 20)/sizeof(Cpp_Token);
array.tokens = push_array(&global_part, Cpp_Token, array.max_count);
Cpp_Lex_Data S = cpp_lex_data_init();
Cpp_Lex_Data S = cpp_lex_data_init(false);
Cpp_Lex_Result result = cpp_lex_step(&S, mem, size+1, HAS_NULL_TERM, &array, NO_OUT_LIMIT);
if (result == LexResult_Finished){

View File

@ -79,19 +79,28 @@ OPEN_FILE_HOOK_SIG(default_file_settings){
Assert(buffer.exists);
bool32 treat_as_code = false;
bool32 treat_as_todo = false;
bool32 wrap_lines = true;
int32_t extension_count = 0;
char **extension_list = get_current_code_extensions(&extension_count);
if (buffer.file_name != 0 && buffer.size < (16 << 20)){
String ext = file_extension(make_string(buffer.file_name, buffer.file_name_len));
String name = make_string(buffer.file_name, buffer.file_name_len);
String ext = file_extension(name);
for (int32_t i = 0; i < extension_count; ++i){
if (match(ext, extension_list[i])){
treat_as_code = true;
break;
}
}
if (!treat_as_code){
String lead_name = front_of_directory(name);
if (match_insensitive(lead_name, "todo.txt")){
treat_as_todo = true;
}
}
}
if (treat_as_code){
@ -107,7 +116,12 @@ OPEN_FILE_HOOK_SIG(default_file_settings){
buffer_set_setting(app, &buffer, BufferSetting_MinimumBaseWrapPosition, default_min_base_width);
buffer_set_setting(app, &buffer, BufferSetting_MapID, map_id);
if (treat_as_code && enable_code_wrapping && buffer.size < (1 << 18)){
if (treat_as_todo){
buffer_set_setting(app, &buffer, BufferSetting_WrapLine, true);
buffer_set_setting(app, &buffer, BufferSetting_LexWithoutStrings, true);
buffer_set_setting(app, &buffer, BufferSetting_VirtualWhitespace, true);
}
else if (treat_as_code && enable_code_wrapping && buffer.size < (1 << 18)){
// NOTE(allen|a4.0.12): There is a little bit of grossness going on here.
// If we set BufferSetting_Lex to true, it will launch a lexing job.
// If a lexing job is active when we set BufferSetting_VirtualWhitespace, the call can fail.

View File

@ -226,6 +226,13 @@ end_bind_helper(Bind_Helper *helper){
return(result);
}
static u32_4tech
get_key_code(char *buffer){
u32_4tech ignore;
u32_4tech result = utf8_to_u32_length_unchecked((u8_4tech*)buffer, &ignore);
return(result);
}
#endif
// BOTTOM

View File

@ -6,6 +6,7 @@
#define FCODER_HELPER_H
#include "4coder_seek_types.h"
#include "4coder_lib/4coder_utf8.h"
static void
exec_command(Application_Links *app, Custom_Command_Function *func){
@ -24,26 +25,46 @@ exec_command(Application_Links *app, Generic_Command cmd){
static int32_t
key_is_unmodified(Key_Event_Data *key){
char *mods = key->modifiers;
int32_t unmodified = !mods[MDFR_CONTROL_INDEX] && !mods[MDFR_ALT_INDEX];
int8_t *mods = key->modifiers;
int32_t unmodified = (!mods[MDFR_CONTROL_INDEX] && !mods[MDFR_ALT_INDEX]);
return(unmodified);
}
static char
to_writable_char(Key_Code long_character){
char character = 0;
if (long_character < ' '){
if (long_character == '\n'){
character = '\n';
}
else if (long_character == '\t'){
character = '\t';
static uint32_t
to_writable_character(User_Input in, uint8_t *character){
uint32_t result = 0;
if (in.type == UserInputKey){
if (in.key.character != 0){
u32_to_utf8_unchecked(in.key.character, character, &result);
}
}
else if (long_character <= 255 && long_character != 127){
character = (char)long_character;
return(result);
}
static uint32_t
to_writable_character(Key_Event_Data key, uint8_t *character){
uint32_t result = 0;
if (key.character != 0){
u32_to_utf8_unchecked(key.character, character, &result);
}
return(character);
return(result);
}
static bool32
backspace_utf8(String *str){
bool32 result = false;
uint8_t *s = (uint8_t*)str->str;
if (str->size > 0){
uint32_t i = str->size-1;
for (; i > 0; --i){
if (s[i] <= 0x7F || s[i] >= 0xC0){
break;
}
}
str->size = i;
result = true;
}
return(result);
}
static bool32
@ -71,18 +92,19 @@ query_user_general(Application_Links *app, Query_Bar *bar, bool32 force_number){
break;
}
char character = 0;
uint8_t character[4];
uint32_t length = 0;
bool32 good_character = false;
if (key_is_unmodified(&in.key)){
if (force_number){
if (in.key.character >= '0' && in.key.character <= '9'){
good_character = true;
character = (char)(in.key.character);
length = to_writable_character(in, character);
}
}
else{
character = to_writable_char(in.key.character);
if (character != 0){
length = to_writable_character(in, character);
if (length != 0){
good_character = true;
}
}
@ -96,12 +118,10 @@ query_user_general(Application_Links *app, Query_Bar *bar, bool32 force_number){
break;
}
else if (in.key.keycode == key_back){
if (bar->string.size > 0){
--bar->string.size;
}
backspace_utf8(&bar->string);
}
else if (good_character){
append_s_char(&bar->string, character);
append_ss(&bar->string, make_string(character, length));
}
}
}
@ -204,7 +224,7 @@ struct Buffer_Rect{
};
#ifndef Swap
#define Swap(T,a,b) do{ T t = a; a = b; b = t; } while(0)
# define Swap(T,a,b) do{ T t = a; a = b; b = t; } while(0)
#endif
static Buffer_Rect

View File

@ -12,32 +12,17 @@
#include "4coder_lib/4coder_mem.h"
struct ID_Pos_Jump_Location{
Buffer_ID buffer_id;
int32_t pos;
};
struct Name_Based_Jump_Location{
String file;
int32_t line;
int32_t column;
};
static void
jump_to_location(Application_Links *app, View_Summary *view, Name_Based_Jump_Location *l){
Buffer_Summary buffer = {0};
if (open_file(app, &buffer, l->file.str, l->file.size, false, true)){
View_Summary target_view = get_first_view_with_buffer(app, buffer.buffer_id);
if (!target_view.exists){
view_set_buffer(app, view, buffer.buffer_id, 0);
target_view = *view;
}
view_set_cursor(app, &target_view, seek_line_char(l->line, l->column), true);
}
}
static void
jump_to_location_always_use_view(Application_Links *app, View_Summary *view, Name_Based_Jump_Location *l){
if (view_open_file(app, view, l->file.str, l->file.size, true)){
view_set_cursor(app, view, seek_line_char(l->line, l->column), true);
}
}
static bool32
ms_style_verify(String line, int32_t paren_pos){
int32_t result = false;

View File

@ -938,12 +938,12 @@ buffer_seek_string_insensitive_backward(Application_Links *app, Buffer_Summary *
// Buffer Line Positioning
//
static int32_t
static bool32
read_line(Application_Links *app, Partition *part, Buffer_Summary *buffer, int32_t line, String *str){
Partial_Cursor begin = {0};
Partial_Cursor end = {0};
int32_t success = 0;
bool32 success = false;
if (buffer_compute_cursor(app, buffer, seek_line_char(line, 1), &begin)){
if (buffer_compute_cursor(app, buffer, seek_line_char(line, -1), &end)){
@ -952,7 +952,7 @@ read_line(Application_Links *app, Partition *part, Buffer_Summary *buffer, int32
int32_t size = (end.pos - begin.pos);
*str = make_string(push_array(part, char, size+1), size+1);
if (str->str){
success = 1;
success = true;
buffer_read_range(app, buffer, begin.pos, end.pos, str->str);
str->size = size;
terminate_with_null(str);

View File

@ -7,15 +7,18 @@ TYPE: 'drop-in-command-pack'
// TOP
#if !defined(FCODER_JUMP_PARSING)
#if !defined(FCODER_JUMP_PARSING) && !defined(FCODER_JUMP_COMMANDS)
#define FCODER_JUMP_PARSING
#define FCODER_JUMP_COMMANDS
#include "4coder_default_framework.h"
#include "4coder_helper/4coder_long_seek.h"
#include "4coder_helper/4coder_helper.h"
#include "4coder_helper/4coder_jump_parsing.h"
#include "4coder_lib/4coder_mem.h"
#include "4coder_jumping.h"
CUSTOM_COMMAND_SIG(goto_jump_at_cursor){
Temp_Memory temp = begin_temp_memory(&global_part);
@ -24,10 +27,12 @@ CUSTOM_COMMAND_SIG(goto_jump_at_cursor){
Name_Based_Jump_Location location = {0};
if (parse_jump_from_buffer_line(app, &global_part, view.buffer_id, view.cursor.line, false, &location)){
change_active_panel(app);
view = get_active_view(app, AccessAll);
jump_to_location(app, &view, &location);
if (auto_center_after_jumps){
center_view(app);
View_Summary target_view = get_active_view(app, AccessAll);
Buffer_Summary buffer = {0};
if (get_jump_buffer(app, &buffer, &location)){
switch_to_existing_view(app, &target_view, &buffer);
jump_to_location(app, &target_view, &buffer, location);
}
}
@ -40,150 +45,17 @@ CUSTOM_COMMAND_SIG(goto_jump_at_cursor_same_panel){
Name_Based_Jump_Location location = {0};
if (parse_jump_from_buffer_line(app, &global_part, view.buffer_id, view.cursor.line, false, &location)){
view = get_active_view(app, AccessAll);
jump_to_location(app, &view, &location);
if (auto_center_after_jumps){
center_view(app);
View_Summary target_view = view;
Buffer_Summary buffer = {0};
if (get_jump_buffer(app, &buffer, &location)){
jump_to_location(app, &target_view, &buffer, location);
}
}
end_temp_memory(temp);
}
//
// Error Jumping
//
static bool32
seek_next_jump_in_buffer(Application_Links *app, Partition *part, int32_t buffer_id, int32_t first_line, bool32 skip_sub_errors, int32_t direction, int32_t *line_out, int32_t *colon_index_out, Name_Based_Jump_Location *location_out){
Assert(direction == 1 || direction == -1);
bool32 result = false;
int32_t line = first_line;
String line_str = {0};
Buffer_Summary buffer = get_buffer(app, buffer_id, AccessAll);
for (;;){
if (read_line(app, part, &buffer, line, &line_str)){
if (parse_jump_location(line_str, location_out, skip_sub_errors, colon_index_out)){
result = true;
break;
}
line += direction;
}
else{
break;
}
}
if (line < 0){
line = 0;
}
*line_out = line;
return(result);
}
static ID_Based_Jump_Location
convert_name_based_to_id_based(Application_Links *app, Name_Based_Jump_Location loc){
ID_Based_Jump_Location result = {0};
Buffer_Summary buffer =
get_buffer_by_name(app, loc.file.str, loc.file.size, AccessAll);
if (buffer.exists){
result.buffer_id = buffer.buffer_id;
result.line = loc.line;
result.column = loc.column;
}
return(result);
}
static int32_t
seek_next_jump_in_view(Application_Links *app, Partition *part, View_Summary *view, int32_t skip_sub_errors, int32_t direction, int32_t *line_out, int32_t *colon_index_out, Name_Based_Jump_Location *location_out){
int32_t result = false;
Name_Based_Jump_Location location = {0};
int32_t line = view->cursor.line;
int32_t colon_index = 0;
if (seek_next_jump_in_buffer(app, part, view->buffer_id, line+direction, skip_sub_errors, direction, &line, &colon_index, &location)){
result = true;
*line_out = line;
*colon_index_out = colon_index;
*location_out = location;
}
return(result);
}
static int32_t
skip_this_jump(ID_Based_Jump_Location prev, ID_Based_Jump_Location jump){
int32_t result = false;
if (prev.buffer_id != 0 &&
prev.buffer_id == jump.buffer_id &&
prev.line == jump.line &&
prev.column <= jump.column){
result = true;
}
return(result);
}
static int32_t
advance_cursor_in_jump_view(Application_Links *app, Partition *part, View_Summary *view, int32_t skip_repeats, int32_t skip_sub_error, int32_t direction, Name_Based_Jump_Location *location_out){
int32_t result = true;
Name_Based_Jump_Location location = {0};
ID_Based_Jump_Location jump = {0};
int32_t line = 0, colon_index = 0;
do{
Temp_Memory temp = begin_temp_memory(part);
if (seek_next_jump_in_view(app, part, view, skip_sub_error, direction, &line, &colon_index, &location)){
jump = convert_name_based_to_id_based(app, location);
view_set_cursor(app, view, seek_line_char(line, colon_index+1), true);
result = true;
}
else{
jump.buffer_id = 0;
result = false;
}
end_temp_memory(temp);
}while(skip_repeats && skip_this_jump(prev_location, jump));
if (result){
*location_out = location;
view_set_cursor(app, view, seek_line_char(line, colon_index+1), true);
}
prev_location = jump;
return(result);
}
static bool32
seek_jump(Application_Links *app, Partition *part, bool32 skip_repeats, bool32 skip_sub_errors, int32_t direction){
bool32 result = false;
View_Summary view = get_view_for_locked_jump_buffer(app);
if (view.exists){
Name_Based_Jump_Location location = {0};
if (advance_cursor_in_jump_view(app, &global_part, &view, skip_repeats, skip_sub_errors, direction, &location)){
View_Summary active_view = get_active_view(app, AccessAll);
if (active_view.view_id == view.view_id){
change_active_panel(app);
active_view = get_active_view(app, AccessAll);
}
jump_to_location(app, &active_view, &location);
result = true;
}
}
return(result);
}
CUSTOM_COMMAND_SIG(goto_next_jump){
bool32 skip_repeats = true;
bool32 skip_sub_errors = true;

200
4coder_jumping.h Normal file
View File

@ -0,0 +1,200 @@
/*
4coder_jumping.h - Routines commonly used when writing code to jump to locations and seek through jump lists.
TYPE: 'helper-routines'
*/
// TOP
#if !defined(FCODER_JUMPING)
#define FCODER_JUMPING
static bool32
get_jump_buffer(Application_Links *app, Buffer_Summary *buffer, Name_Based_Jump_Location *location){
bool32 result = open_file(app, buffer, location->file.str, location->file.size, false, true);
return(result);
}
static bool32
get_jump_buffer(Application_Links *app, Buffer_Summary *buffer, ID_Pos_Jump_Location *location){
*buffer = get_buffer(app, location->buffer_id, AccessAll);
bool32 result = false;
if (buffer->exists){
result = true;
}
return(result);
}
static void
switch_to_existing_view(Application_Links *app, View_Summary *view, Buffer_Summary *buffer){
if (!(view->exists && view->buffer_id == buffer->buffer_id)){
View_Summary existing_view = get_first_view_with_buffer(app, buffer->buffer_id);
if (existing_view.exists){
*view = existing_view;
}
}
}
static void
set_view_to_location(Application_Links *app, View_Summary *view, Buffer_Summary *buffer, Buffer_Seek seek){
if (view->buffer_id != buffer->buffer_id){
view_set_buffer(app, view, buffer->buffer_id, 0);
}
view_set_cursor(app, view, seek, true);
}
static void
jump_to_location(Application_Links *app, View_Summary *view, Buffer_Summary *buffer, Name_Based_Jump_Location location){
set_active_view(app, view);
set_view_to_location(app, view, buffer, seek_line_char(location.line, location.column));
if (auto_center_after_jumps){
center_view(app);
}
}
static void
jump_to_location(Application_Links *app, View_Summary *view, Buffer_Summary *buffer, ID_Pos_Jump_Location location){
set_active_view(app, view);
set_view_to_location(app, view, buffer, seek_pos(location.pos));
if (auto_center_after_jumps){
center_view(app);
}
}
//
// Error Jumping
//
static bool32
seek_next_jump_in_buffer(Application_Links *app, Partition *part, int32_t buffer_id, int32_t first_line, bool32 skip_sub_errors, int32_t direction, int32_t *line_out, int32_t *colon_index_out, Name_Based_Jump_Location *location_out){
Assert(direction == 1 || direction == -1);
bool32 result = false;
int32_t line = first_line;
String line_str = {0};
Buffer_Summary buffer = get_buffer(app, buffer_id, AccessAll);
for (;;){
if (read_line(app, part, &buffer, line, &line_str)){
if (parse_jump_location(line_str, location_out, skip_sub_errors, colon_index_out)){
result = true;
break;
}
line += direction;
}
else{
break;
}
}
if (line < 0){
line = 0;
}
*line_out = line;
return(result);
}
static ID_Based_Jump_Location
convert_name_based_to_id_based(Application_Links *app, Name_Based_Jump_Location loc){
ID_Based_Jump_Location result = {0};
Buffer_Summary buffer = get_buffer_by_name(app, loc.file.str, loc.file.size, AccessAll);
if (buffer.exists){
result.buffer_id = buffer.buffer_id;
result.line = loc.line;
result.column = loc.column;
}
return(result);
}
static int32_t
seek_next_jump_in_view(Application_Links *app, Partition *part, View_Summary *view, int32_t skip_sub_errors, int32_t direction, int32_t *line_out, int32_t *colon_index_out, Name_Based_Jump_Location *location_out){
int32_t result = false;
Name_Based_Jump_Location location = {0};
int32_t line = view->cursor.line;
int32_t colon_index = 0;
if (seek_next_jump_in_buffer(app, part, view->buffer_id, line+direction, skip_sub_errors, direction, &line, &colon_index, &location)){
result = true;
*line_out = line;
*colon_index_out = colon_index;
*location_out = location;
}
return(result);
}
static bool32
skip_this_jump(ID_Based_Jump_Location prev, ID_Based_Jump_Location jump){
bool32 result = false;
if (prev.buffer_id != 0 && prev.buffer_id == jump.buffer_id && prev.line == jump.line && prev.column <= jump.column){
result = true;
}
return(result);
}
static bool32
advance_cursor_in_jump_view(Application_Links *app, Partition *part, View_Summary *view, int32_t skip_repeats, int32_t skip_sub_error, int32_t direction, Name_Based_Jump_Location *location_out){
bool32 result = true;
Name_Based_Jump_Location location = {0};
ID_Based_Jump_Location jump = {0};
int32_t line = 0, colon_index = 0;
do{
Temp_Memory temp = begin_temp_memory(part);
if (seek_next_jump_in_view(app, part, view, skip_sub_error, direction, &line, &colon_index, &location)){
jump = convert_name_based_to_id_based(app, location);
view_set_cursor(app, view, seek_line_char(line, colon_index+1), true);
result = true;
}
else{
jump.buffer_id = 0;
result = false;
}
end_temp_memory(temp);
}while(skip_repeats && skip_this_jump(prev_location, jump));
if (result){
*location_out = location;
view_set_cursor(app, view, seek_line_char(line, colon_index+1), true);
}
prev_location = jump;
return(result);
}
static bool32
seek_jump(Application_Links *app, Partition *part, bool32 skip_repeats, bool32 skip_sub_errors, int32_t direction){
bool32 result = false;
View_Summary view = get_view_for_locked_jump_buffer(app);
if (view.exists){
Name_Based_Jump_Location location = {0};
if (advance_cursor_in_jump_view(app, &global_part, &view, skip_repeats, skip_sub_errors, direction, &location)){
Buffer_Summary buffer = {0};
if (get_jump_buffer(app, &buffer, &location)){
View_Summary target_view = get_active_view(app, AccessAll);
if (target_view.view_id == view.view_id){
change_active_panel(app);
target_view = get_active_view(app, AccessAll);
}
switch_to_existing_view(app, &target_view, &buffer);
jump_to_location(app, &target_view, &buffer, location);
result = true;
}
}
}
return(result);
}
#endif
// BOTTOM

View File

@ -148,6 +148,8 @@ end_tail_part(Tail_Temp_Partition temp){
}
}
#define reset_temp_memory end_temp_memory
/*
NOTE(allen):
This is a very week general purpose allocator system.
@ -339,8 +341,7 @@ general_memory_reallocate(General_Memory *general, void *old, i32_4tech old_size
i32_4tech additional_space = size - bubble->size;
if (additional_space > 0){
Bubble *next = bubble->next;
if (!(next->flags & MEM_BUBBLE_USED) &&
next->size + (i32_4tech)sizeof(Bubble) >= additional_space){
if (!(next->flags & MEM_BUBBLE_USED) && next->size + (i32_4tech)sizeof(Bubble) >= additional_space){
general_memory_do_merge(bubble, next);
general_memory_attempt_split(general, bubble, size);
}
@ -359,10 +360,11 @@ general_memory_reallocate_nocopy(General_Memory *general, void *old, i32_4tech s
return(result);
}
#define reset_temp_memory end_temp_memory
#define gen_struct(g, T) (T*)general_memory_allocate(g, sizeof(T), 0)
#define gen_array(g, T, size) (T*)general_memory_allocate(g, sizeof(T)*(size))
#define gen_block(g, size) general_memory_open(g, size, 0)
#define gen_realloc_array(g, T, old, old_size, size)\
(T*)general_memory_reallocate(g, old, old_size*sizeof(T), size*sizeof(T))
#endif

View File

@ -199,7 +199,7 @@ load_project_from_file(Application_Links *app, Partition *part, FILE *file, Stri
array.max_count = (1 << 20)/sizeof(Cpp_Token);
array.tokens = push_array(&global_part, Cpp_Token, array.max_count);
Cpp_Lex_Data S = cpp_lex_data_init();
Cpp_Lex_Data S = cpp_lex_data_init(false);
Cpp_Lex_Result result = cpp_lex_step(&S, mem, size+1, HAS_NULL_TERM, &array, NO_OUT_LIMIT);
if (result == LexResult_Finished){

View File

@ -1,5 +1,5 @@
/*
4cpp_lexer.h - Preversioning
4cpp_lexer.h - 1.0.2
no warranty implied; use at your own risk
This software is in the public domain. Where that dedication is not
@ -66,6 +66,8 @@ struct String_And_Flag{
static String_And_Flag preprops[] = {
{make_stafl("include" , CPP_PP_INCLUDE )} ,
{make_stafl("INCLUDE" , CPP_PP_INCLUDE )} ,
{make_stafl("version" , CPP_PP_VERSION )} ,
{make_stafl("VERSION" , CPP_PP_VERSION )} ,
{make_stafl("ifndef" , CPP_PP_IFNDEF )} ,
{make_stafl("IFNDEF" , CPP_PP_IFNDEF )} ,
{make_stafl("define" , CPP_PP_DEFINE )} ,
@ -185,7 +187,7 @@ static String_And_Flag keywords[] = {
{make_stafl("thread_local" , CPP_TOKEN_KEY_OTHER)},
#if defined(FCPP_LEXER_EXTRA_KEYWORDS)
FCPP_LEXER_EXTRA_KEYWORDS
#include FCPP_LEXER_EXTRA_KEYWORDS
#endif
};
static i32_4tech keywords_count = sizeof(keywords)/sizeof(keywords[0]);
@ -289,6 +291,7 @@ cpp_pp_directive_to_state(Cpp_Token_Type type){
result = LSPP_body;
break;
case CPP_PP_VERSION:
case CPP_PP_LINE:
result = LSPP_number;
break;
@ -383,6 +386,9 @@ cpp_lex_nonalloc_null_end_no_limit(Cpp_Lex_Data *S_ptr, char *chunk, i32_4tech s
S.pp_state -= LSPP_count;
}
if (S.pp_state == LSPP_default && S.ignore_string_delims){
S.pp_state = LSPP_no_strings;
}
S.token.state_flags = S.pp_state;
S.token_start = S.pos;
@ -448,7 +454,7 @@ cpp_lex_nonalloc_null_end_no_limit(Cpp_Lex_Data *S_ptr, char *chunk, i32_4tech s
#undef OperCase
case '\\':
if (S.pp_state == LSPP_default){
if (S.pp_state == LSPP_default || S.pp_state == LSPP_no_strings){
S.token.type = CPP_TOKEN_JUNK;
}
else{
@ -873,6 +879,9 @@ cpp_lex_nonalloc_null_end_no_limit(Cpp_Lex_Data *S_ptr, char *chunk, i32_4tech s
--S.pos;
}
if (S.pp_state == LSPP_default && S.ignore_string_delims){
S.pp_state = LSPP_no_strings;
}
if ((S.token.flags & CPP_TFLAG_PP_DIRECTIVE) == 0){
switch (S.pp_state){
case LSPP_macro_identifier:
@ -921,7 +930,7 @@ cpp_lex_nonalloc_null_end_no_limit(Cpp_Lex_Data *S_ptr, char *chunk, i32_4tech s
S.token.size = S.pos - S.token_start;
}
if ((S.token.flags & CPP_TFLAG_PP_DIRECTIVE) == 0){
if (S.pp_state != LSPP_default){
if (S.pp_state != LSPP_default && S.pp_state){
S.token.flags |= CPP_TFLAG_PP_BODY;
}
}
@ -1035,20 +1044,15 @@ CODE_EXAMPLE(
Cpp_Token_Array lex_file(char *file_name){
File_Data file = read_whole_file(file_name);
char *temp = (char*)malloc(4096); // hopefully big enough
Cpp_Lex_Data lex_state = cpp_lex_data_init(temp);
Cpp_Lex_Data lex_state = cpp_lex_data_init(false);
Cpp_Token_Array array = {0};
array.tokens = (Cpp_Token*)malloc(1 << 20); // hopefully big enough
array.max_count = (1 << 20)/sizeof(Cpp_Token);
Cpp_Lex_Result result =
cpp_lex_step(&lex_state, file.data, file.size, file.size,
&array, NO_OUT_LIMIT);
Cpp_Lex_Result result = cpp_lex_step(&lex_state, file.data, file.size, file.size, &array, NO_OUT_LIMIT);
Assert(result == LexResult_Finished);
free(temp);
return(array);
})
@ -1078,7 +1082,8 @@ DOC_SEE(Cpp_Lex_Result)
}
API_EXPORT FCPP_LINK Cpp_Lex_Data
cpp_lex_data_init()/*
cpp_lex_data_init(b32_4tech ignore_string_delims)/*
DOC_PARAM(ignore_string_delims, TODO)
DOC_RETURN(A brand new lex state ready to begin lexing a file from the beginning.)
DOC(Creates a new lex state in the form of a Cpp_Lex_Data struct and returns the struct.
@ -1087,6 +1092,7 @@ enough but the buffer is not checked, so to be 100% bullet proof it has to be th
as the file being lexed.)
*/{
Cpp_Lex_Data data = {0};
data.ignore_string_delims = ignore_string_delims;
return(data);
}
@ -1120,10 +1126,6 @@ DOC_SEE(cpp_lex_data_new_temp)
}
}
API_EXPORT FCPP_LINK void
cpp_lex_data_new_temp_DEP(Cpp_Lex_Data *lex_data, char *new_buffer)
/*DOC(Deprecated in 4cpp Lexer 1.0.1*/{}
FCPP_LINK char
cpp_token_get_pp_state(u16_4tech bitfield){
return (char)(bitfield);
@ -1188,7 +1190,7 @@ The start and end points are based on the edited region of the file before the e
}
API_EXPORT FCPP_LINK Cpp_Relex_Data
cpp_relex_init(Cpp_Token_Array *array, i32_4tech start_pos, i32_4tech end_pos, i32_4tech character_shift_amount)
cpp_relex_init(Cpp_Token_Array *array, i32_4tech start_pos, i32_4tech end_pos, i32_4tech character_shift_amount, b32_4tech ignore_string_delims)
/*
DOC_PARAM(array, A pointer to the token array that will be modified by the relex,
this array should already contain the tokens for the previous state of the file.)
@ -1199,6 +1201,7 @@ In particular, end_pos is the first character after the edited region not effect
Thus if the edited region contained one character end_pos - start_pos should equal 1.
The start and end points are based on the edited region of the file before the edit.)
DOC_PARAM(character_shift_amount, The shift in the characters after the edited region.)
DOC_PARAM(ignore_string_delims, TODO)
DOC_RETURN(Returns a partially initialized relex state.)
DOC(This call does the first setup step of initializing a relex state. To finish initializing the relex state
@ -1224,7 +1227,7 @@ DOC_SEE(cpp_relex_is_start_chunk)
state.character_shift_amount = character_shift_amount;
state.lex = cpp_lex_data_init();
state.lex = cpp_lex_data_init(ignore_string_delims);
state.lex.pp_state = cpp_token_get_pp_state(array->tokens[state.start_token_index].state_flags);
state.lex.pos = state.relex_start_position;
@ -1581,7 +1584,7 @@ return(array);
)
DOC_SEE(cpp_make_token_array)
*/{
Cpp_Lex_Data S = cpp_lex_data_init();
Cpp_Lex_Data S = cpp_lex_data_init(false);
i32_4tech quit = 0;
char empty = 0;

View File

@ -1,13 +1,13 @@
uint16_t whitespace_fsm_eq_classes[] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 9,18, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0,10,20,10,10,10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
};
const int32_t num_whitespace_fsm_eq_classes = 3;
uint8_t whitespace_fsm_table[] = {
9,10,11,12,13,14,15,16,17,
0, 1, 2, 3, 4, 5, 6, 7, 8,
0, 0, 0, 0, 0, 0, 0, 0, 0,
10,11,12,13,14,15,16,17,18,19,
0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
};
uint16_t int_fsm_eq_classes[] = {
@ -359,6 +359,44 @@ uint8_t pp_junk_fsm_table[] = {
31,41,42,43,44, 5, 6, 5, 8, 9, 8,51,52,53,54,55,56,57,18,18,20,20,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,39,
};
uint16_t no_string_fsm_eq_classes[] = {
0,40,40,40,40,40,40,40,40,40,80,120,120,120,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,160,200,240,280,320,360,400,240,440,440,480,520,440,560,600,640,680,720,720,720,720,720,720,720,720,720,760,440,800,840,880,440,440,920,920,920,920,920,920,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,440,960,440,1000,320,40,920,920,920,920,1040,920,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,1080,240,240,440,1120,440,440,40,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,
};
const int32_t num_no_string_fsm_eq_classes = 29;
uint8_t no_string_fsm_table[] = {
40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,
0,41,42,43,44,48,48,48,48,48,48,51,52,53,54,55,56,57,18,18,20,20,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,39,
0,41,42,43,44,48,48,48,48,48,48,51,52,53,54,55,56,57,58,18,20,20,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,39,
0,41,42, 3,44,48,48,48,48,48,48,51,52,53,54,55,56,57,18,19,20,20,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,39,
0,41,42, 3,44,48,48,48,48,48,48,51,52,53,54,55,56,57,18,18,20,20,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,39,
38,41,42,43,44,48,48,48,48,48,48,51,52,53,54,55,56,57,18,18,20,20,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,39,
1, 1,42, 4, 4,48,48,48,48,48,48,51,52,53,54,55,56,57,18,18,20,20,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,39,
3,41,42,43,44,48,48,48,48,48,48,51,52,53,54,55,56,57,18,18,20,20,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,39,
1, 1,42,43,44,48,48,48,48,48,48,51,52,53,54,55,56,57,18,18,20,20,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,39,
35,41,42,43,44,48,48,48,48,48,48,51,52,53,54,55,56,57,18,18,20,20,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,39,
30,41,42,43,44,48,48,48,48,48,48,51,52,53,54,55,56,57,18,18,20,20,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,39,
40,41,42,43,44,48,48,48,48,48,48,51,52,53,54,55,56,57,18,18,20,20,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,39,
34,41,42,43,44,48,48,48,48,48,48,51,52,53,54,55,56,20,18,18,21,21,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,39,
32,41,42,43,44,48,48,48,48,48,48,51,52,53,54,55,56,57,18,18,20,20,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,39,
28,41,42,43,44,48,48,48,48,48,48,51,52,53,15,55,56,57,18,18,20,20,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,39,
22,41,42,43,44,48,48,48,48,48,48,13,13,53,54,55,56,57,18,18,20,20,23,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,39,
17,41,42,43,44,48,48,48,48,48,48,51,52,53,54,55,56,18,18,18,20,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,39,
12, 1,42,43,44,48,48,48,48,48,48,11,11,13,15,15,16,57,18,18,20,20,13,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,39,
11, 1,42,43,44,48,48,48,48,48,48,11,11,13,15,15,16,57,18,18,20,20,13,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,39,
33,41,42,43,44,48,48,48,48,48,48,51,52,53,54,55,56,57,18,18,20,20,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,39,
24,41,42,43,44,48,48,48,48,48,48,51,52,53,54,55,56,57,18,18,20,20,62,63,25,65,66,67,68,69,70,71,72,73,74,75,76,77,78,39,
37,41,42,43,44,48,48,48,48,48,48,51,52,53,54,55,56,57,18,18,20,20,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,39,
26,41,42,43,44,48,48,48,48,48,48,51,52,53,54,55,56,57,18,18,20,20,62,63,64,65,27,67,29,69,70,71,72,73,74,75,76,77,78,39,
1, 1,42, 4, 4,48,48,48,48,48,48,51,52,53,54,55,16,57,18,18,20,20,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,39,
40,41,42,43,44,48,48,48,48,48,48,51,52,53,54,55,56,57,19,18,20,20,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,39,
36,41,42,43,44,48,48,48,48,48,48,51,52,53,54,55,56,57,18,18,20,20,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,39,
1, 1,42, 4, 4,48,48,48,48,48,48,51,52,14,54,55,16,57,18,18,20,20,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,39,
1, 1,42, 4, 4,48,48,48,48,48,48,51,16,53,54,55,56,57,18,18,20,20,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,39,
31,41,42,43,44,48,48,48,48,48,48,51,52,53,54,55,56,57,18,18,20,20,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,39,
};
uint16_t * get_eq_classes[] = {
main_fsm_eq_classes,
pp_include_fsm_eq_classes,
@ -369,6 +407,7 @@ pp_body_fsm_eq_classes,
pp_number_fsm_eq_classes,
pp_error_fsm_eq_classes,
pp_junk_fsm_eq_classes,
no_string_fsm_eq_classes,
};
uint8_t * get_table[] = {
@ -381,5 +420,6 @@ pp_body_fsm_table,
pp_number_fsm_table,
pp_error_fsm_table,
pp_junk_fsm_table,
no_string_fsm_table,
};

View File

@ -23,211 +23,212 @@ ENUM(uint32_t, Cpp_Token_Type){
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_VERSION = 3,
CPP_PP_DEFINE = 4,
CPP_PP_UNDEF = 5,
CPP_PP_IF = 6,
CPP_PP_IFDEF = 7,
CPP_PP_IFNDEF = 8,
CPP_PP_ELSE = 9,
CPP_PP_ELIF = 10,
CPP_PP_ENDIF = 11,
CPP_PP_ERROR = 12,
CPP_PP_IMPORT = 13,
CPP_PP_USING = 14,
CPP_PP_LINE = 15,
CPP_PP_PRAGMA = 16,
CPP_PP_STRINGIFY = 17,
CPP_PP_CONCAT = 18,
CPP_PP_UNKNOWN = 19,
CPP_PP_DEFINED = 19,
CPP_PP_INCLUDE_FILE = 20,
CPP_PP_ERROR_MESSAGE = 21,
CPP_PP_DEFINED = 20,
CPP_PP_INCLUDE_FILE = 21,
CPP_PP_ERROR_MESSAGE = 22,
CPP_TOKEN_KEY_TYPE = 22,
CPP_TOKEN_KEY_MODIFIER = 23,
CPP_TOKEN_KEY_QUALIFIER = 24,
CPP_TOKEN_KEY_TYPE = 23,
CPP_TOKEN_KEY_MODIFIER = 24,
CPP_TOKEN_KEY_QUALIFIER = 25,
/* DOC(This type is not stored in token output from the lexer.) */
CPP_TOKEN_KEY_OPERATOR = 25,
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_KEY_OPERATOR = 26,
CPP_TOKEN_KEY_CONTROL_FLOW = 27,
CPP_TOKEN_KEY_CAST = 28,
CPP_TOKEN_KEY_TYPE_DECLARATION = 29,
CPP_TOKEN_KEY_ACCESS = 30,
CPP_TOKEN_KEY_LINKAGE = 31,
CPP_TOKEN_KEY_OTHER = 32,
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_IDENTIFIER = 33,
CPP_TOKEN_INTEGER_CONSTANT = 34,
CPP_TOKEN_CHARACTER_CONSTANT = 35,
CPP_TOKEN_FLOATING_CONSTANT = 36,
CPP_TOKEN_STRING_CONSTANT = 37,
CPP_TOKEN_BOOLEAN_CONSTANT = 38,
CPP_TOKEN_STATIC_ASSERT = 38,
CPP_TOKEN_STATIC_ASSERT = 39,
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_BRACKET_OPEN = 40,
CPP_TOKEN_BRACKET_CLOSE = 41,
CPP_TOKEN_PARENTHESE_OPEN = 42,
CPP_TOKEN_PARENTHESE_CLOSE = 43,
CPP_TOKEN_BRACE_OPEN = 44,
CPP_TOKEN_BRACE_CLOSE = 45,
CPP_TOKEN_SEMICOLON = 46,
CPP_TOKEN_ELLIPSIS = 47,
/* DOC(This is an 'ambiguous' token type because it requires
parsing to determine the full nature of the token.) */
CPP_TOKEN_STAR = 47,
CPP_TOKEN_STAR = 48,
/* DOC(This is an 'ambiguous' token type because it requires
parsing to determine the full nature of the token.) */
CPP_TOKEN_AMPERSAND = 48,
CPP_TOKEN_AMPERSAND = 49,
/* DOC(This is an 'ambiguous' token type because it requires
parsing to determine the full nature of the token.) */
CPP_TOKEN_TILDE = 49,
CPP_TOKEN_TILDE = 50,
/* DOC(This is an 'ambiguous' token type because it requires
parsing to determine the full nature of the token.) */
CPP_TOKEN_PLUS = 50,
CPP_TOKEN_PLUS = 51,
/* DOC(This is an 'ambiguous' token type because it requires
parsing to determine the full nature of the token.) */
CPP_TOKEN_MINUS = 51,
CPP_TOKEN_MINUS = 52,
/* DOC(This is an 'ambiguous' token type because it requires
parsing to determine the full nature of the token.) */
CPP_TOKEN_INCREMENT = 52,
CPP_TOKEN_INCREMENT = 53,
/* DOC(This is an 'ambiguous' token type because it requires
parsing to determine the full nature of the token.) */
CPP_TOKEN_DECREMENT = 53,
CPP_TOKEN_DECREMENT = 54,
// NOTE(allen): Precedence 1, LtoR
CPP_TOKEN_SCOPE = 54,
CPP_TOKEN_SCOPE = 55,
// NOTE(allen): Precedence 2, LtoR
/* DOC(This type is for parser use, it is not output by the lexer.) */
CPP_TOKEN_POSTINC = 55,
CPP_TOKEN_POSTINC = 56,
/* DOC(This type is for parser use, it is not output by the lexer.) */
CPP_TOKEN_POSTDEC = 56,
CPP_TOKEN_POSTDEC = 57,
/* DOC(This type is for parser use, it is not output by the lexer.) */
CPP_TOKEN_FUNC_STYLE_CAST = 57,
CPP_TOKEN_CPP_STYLE_CAST = 58,
CPP_TOKEN_FUNC_STYLE_CAST = 58,
CPP_TOKEN_CPP_STYLE_CAST = 59,
/* DOC(This type is for parser use, it is not output by the lexer.) */
CPP_TOKEN_CALL = 59,
CPP_TOKEN_CALL = 60,
/* DOC(This type is for parser use, it is not output by the lexer.) */
CPP_TOKEN_INDEX = 60,
CPP_TOKEN_DOT = 61,
CPP_TOKEN_ARROW = 62,
CPP_TOKEN_INDEX = 61,
CPP_TOKEN_DOT = 62,
CPP_TOKEN_ARROW = 63,
// NOTE(allen): Precedence 3, RtoL
/* DOC(This token is for parser use, it is not output by the lexer.) */
CPP_TOKEN_PREINC = 63,
CPP_TOKEN_PREINC = 64,
/* DOC(This token is for parser use, it is not output by the lexer.) */
CPP_TOKEN_PREDEC = 64,
CPP_TOKEN_PREDEC = 65,
/* DOC(This token is for parser use, it is not output by the lexer.) */
CPP_TOKEN_POSITIVE = 65,
CPP_TOKEN_POSITIVE = 66,
/* DOC(This token is for parser use, it is not output by the lexer.) */
CPP_TOKEN_NEGAITVE = 66,
CPP_TOKEN_NOT = 67,
CPP_TOKEN_NEGAITVE = 67,
CPP_TOKEN_NOT = 68,
/* DOC(This type is for parser use, it is not output by the lexer.) */
CPP_TOKEN_BIT_NOT = 68,
CPP_TOKEN_BIT_NOT = 69,
/* DOC(This type is for parser use, it is not output by the lexer.) */
CPP_TOKEN_CAST = 69,
CPP_TOKEN_CAST = 70,
/* DOC(This type is for parser use, it is not output by the lexer.) */
CPP_TOKEN_DEREF = 70,
CPP_TOKEN_DEREF = 71,
/* DOC(This type is for parser use, it is not output by the lexer.) */
CPP_TOKEN_TYPE_PTR = 71,
CPP_TOKEN_TYPE_PTR = 72,
/* DOC(This type is for parser use, it is not output by the lexer.) */
CPP_TOKEN_ADDRESS = 72,
CPP_TOKEN_ADDRESS = 73,
/* DOC(This type is for parser use, it is not output by the lexer.) */
CPP_TOKEN_TYPE_REF = 73,
CPP_TOKEN_SIZEOF = 74,
CPP_TOKEN_ALIGNOF = 75,
CPP_TOKEN_DECLTYPE = 76,
CPP_TOKEN_TYPEID = 77,
CPP_TOKEN_NEW = 78,
CPP_TOKEN_DELETE = 79,
CPP_TOKEN_TYPE_REF = 74,
CPP_TOKEN_SIZEOF = 75,
CPP_TOKEN_ALIGNOF = 76,
CPP_TOKEN_DECLTYPE = 77,
CPP_TOKEN_TYPEID = 78,
CPP_TOKEN_NEW = 79,
CPP_TOKEN_DELETE = 80,
/* DOC(This type is for parser use, it is not output by the lexer.) */
CPP_TOKEN_NEW_ARRAY = 80,
CPP_TOKEN_NEW_ARRAY = 81,
/* DOC(This type is for parser use, it is not output by the lexer.) */
CPP_TOKEN_DELETE_ARRAY = 81,
CPP_TOKEN_DELETE_ARRAY = 82,
// NOTE(allen): Precedence 4, LtoR
CPP_TOKEN_PTRDOT = 82,
CPP_TOKEN_PTRARROW = 83,
CPP_TOKEN_PTRDOT = 83,
CPP_TOKEN_PTRARROW = 84,
// NOTE(allen): Precedence 5, LtoR
/* DOC(This type is for parser use, it is not output by the lexer.) */
CPP_TOKEN_MUL = 84,
CPP_TOKEN_DIV = 85,
CPP_TOKEN_MOD = 86,
CPP_TOKEN_MUL = 85,
CPP_TOKEN_DIV = 86,
CPP_TOKEN_MOD = 87,
// NOTE(allen): Precedence 6, LtoR
/* DOC(This type is for parser use, it is not output by the lexer.) */
CPP_TOKEN_ADD = 87,
CPP_TOKEN_ADD = 88,
/* DOC(This type is for parser use, it is not output by the lexer.) */
CPP_TOKEN_SUB = 88,
CPP_TOKEN_SUB = 89,
// NOTE(allen): Precedence 7, LtoR
CPP_TOKEN_LSHIFT = 89,
CPP_TOKEN_RSHIFT = 90,
CPP_TOKEN_LSHIFT = 90,
CPP_TOKEN_RSHIFT = 91,
// NOTE(allen): Precedence 8, LtoR
CPP_TOKEN_LESS = 91,
CPP_TOKEN_GRTR = 92,
CPP_TOKEN_GRTREQ = 93,
CPP_TOKEN_LESSEQ = 94,
CPP_TOKEN_LESS = 92,
CPP_TOKEN_GRTR = 93,
CPP_TOKEN_GRTREQ = 94,
CPP_TOKEN_LESSEQ = 95,
// NOTE(allen): Precedence 9, LtoR
CPP_TOKEN_EQEQ = 95,
CPP_TOKEN_NOTEQ = 96,
CPP_TOKEN_EQEQ = 96,
CPP_TOKEN_NOTEQ = 97,
// NOTE(allen): Precedence 10, LtoR
/* DOC(This type is for parser use, it is not output by the lexer.) */
CPP_TOKEN_BIT_AND = 97,
CPP_TOKEN_BIT_AND = 98,
// NOTE(allen): Precedence 11, LtoR
CPP_TOKEN_BIT_XOR = 98,
CPP_TOKEN_BIT_XOR = 99,
// NOTE(allen): Precedence 12, LtoR
CPP_TOKEN_BIT_OR = 99,
CPP_TOKEN_BIT_OR = 100,
// NOTE(allen): Precedence 13, LtoR
CPP_TOKEN_AND = 100,
CPP_TOKEN_AND = 101,
// NOTE(allen): Precedence 14, LtoR
CPP_TOKEN_OR = 101,
CPP_TOKEN_OR = 102,
// NOTE(allen): Precedence 15, RtoL
CPP_TOKEN_TERNARY_QMARK = 102,
CPP_TOKEN_COLON = 103,
CPP_TOKEN_THROW = 104,
CPP_TOKEN_EQ = 105,
CPP_TOKEN_ADDEQ = 106,
CPP_TOKEN_SUBEQ = 107,
CPP_TOKEN_MULEQ = 108,
CPP_TOKEN_DIVEQ = 109,
CPP_TOKEN_MODEQ = 110,
CPP_TOKEN_LSHIFTEQ = 111,
CPP_TOKEN_RSHIFTEQ = 112,
CPP_TOKEN_ANDEQ = 113,
CPP_TOKEN_OREQ = 114,
CPP_TOKEN_XOREQ = 115,
CPP_TOKEN_TERNARY_QMARK = 103,
CPP_TOKEN_COLON = 104,
CPP_TOKEN_THROW = 105,
CPP_TOKEN_EQ = 106,
CPP_TOKEN_ADDEQ = 107,
CPP_TOKEN_SUBEQ = 108,
CPP_TOKEN_MULEQ = 109,
CPP_TOKEN_DIVEQ = 110,
CPP_TOKEN_MODEQ = 111,
CPP_TOKEN_LSHIFTEQ = 112,
CPP_TOKEN_RSHIFTEQ = 113,
CPP_TOKEN_ANDEQ = 114,
CPP_TOKEN_OREQ = 115,
CPP_TOKEN_XOREQ = 116,
// NOTE(allen): Precedence 16, LtoR
CPP_TOKEN_COMMA = 116,
CPP_TOKEN_COMMA = 117,
/* DOC(This type is for parser use, it is not output by the lexer.) */
CPP_TOKEN_EOF = 117,
CPP_TOKEN_EOF = 118,
CPP_TOKEN_TYPE_COUNT = 118
CPP_TOKEN_TYPE_COUNT = 119
};
/* DOC(Cpp_Token represents a single lexed token. It is the primary output of the lexing system.)
@ -335,6 +336,8 @@ STRUCT Cpp_Lex_Data{
Cpp_Token token;
int32_t ignore_string_delims;
int32_t __pc__;
};
@ -374,61 +377,61 @@ STRUCT Cpp_Relex_Data{
};
ENUM_INTERNAL(uint16_t, Cpp_Preprocessor_State){
CPP_LEX_PP_DEFAULT,
CPP_LEX_PP_IDENTIFIER,
CPP_LEX_PP_MACRO_IDENTIFIER,
CPP_LEX_PP_INCLUDE,
CPP_LEX_PP_BODY,
CPP_LEX_PP_BODY_IF,
CPP_LEX_PP_NUMBER,
CPP_LEX_PP_ERROR,
CPP_LEX_PP_JUNK,
CPP_LEX_PP_COUNT
CPP_LEX_PP_DEFAULT = 0,
CPP_LEX_PP_IDENTIFIER = 1,
CPP_LEX_PP_MACRO_IDENTIFIER = 2,
CPP_LEX_PP_INCLUDE = 3,
CPP_LEX_PP_BODY = 4,
CPP_LEX_PP_BODY_IF = 5,
CPP_LEX_PP_NUMBER = 6,
CPP_LEX_PP_ERROR = 7,
CPP_LEX_PP_JUNK = 8,
CPP_LEX_PP_COUNT = 9
};
ENUM_INTERNAL(uint8_t, Cpp_Lex_State){
LS_default,
LS_identifier,
LS_pound,
LS_pp,
LS_ppdef,
LS_char,
LS_char_multiline,
LS_char_slashed,
LS_string,
LS_string_multiline,
LS_string_slashed,
LS_number,
LS_number0,
LS_float,
LS_crazy_float0,
LS_crazy_float1,
LS_hex,
LS_comment_pre,
LS_comment,
LS_comment_slashed,
LS_comment_block,
LS_comment_block_ending,
LS_dot,
LS_ellipsis,
LS_less,
LS_less_less,
LS_more,
LS_more_more,
LS_minus,
LS_arrow,
LS_and,
LS_or,
LS_plus,
LS_colon,
LS_star,
LS_modulo,
LS_caret,
LS_eq,
LS_bang,
LS_error_message,
LS_default = 0,
LS_identifier = 1,
LS_pound = 2,
LS_pp = 3,
LS_ppdef = 4,
LS_char = 5,
LS_char_multiline = 6,
LS_char_slashed = 7,
LS_string = 8,
LS_string_multiline = 9,
LS_string_slashed = 10,
LS_number = 11,
LS_number0 = 12,
LS_float = 13,
LS_crazy_float0 = 14,
LS_crazy_float1 = 15,
LS_hex = 16,
LS_comment_pre = 17,
LS_comment = 18,
LS_comment_slashed = 19,
LS_comment_block = 20,
LS_comment_block_ending = 21,
LS_dot = 22,
LS_ellipsis = 23,
LS_less = 24,
LS_less_less = 25,
LS_more = 26,
LS_more_more = 27,
LS_minus = 28,
LS_arrow = 29,
LS_and = 30,
LS_or = 31,
LS_plus = 32,
LS_colon = 33,
LS_star = 34,
LS_modulo = 35,
LS_caret = 36,
LS_eq = 37,
LS_bang = 38,
LS_error_message = 39,
//
LS_count
LS_count = 40
};
ENUM_INTERNAL(uint8_t, Cpp_Lex_Int_State){
@ -454,6 +457,7 @@ ENUM_INTERNAL(uint8_t, Cpp_Lex_PP_State){
LSPP_number,
LSPP_error,
LSPP_junk,
LSPP_no_strings,
//
LSPP_count
};

89
4ed.cpp
View File

@ -1679,15 +1679,15 @@ App_Step_Sig(app_step){
}
}
b32 mouse_on_divider = 0;
b32 mouse_divider_vertical = 0;
b32 mouse_on_divider = false;
b32 mouse_divider_vertical = false;
i32 mouse_divider_id = 0;
i32 mouse_divider_side = 0;
if (mouse_in_margin_area){
Panel *panel = mouse_panel;
if (mx >= panel->inner.x0 && mx < panel->inner.x1){
mouse_divider_vertical = 0;
mouse_divider_vertical = false;
if (my > panel->inner.y0){
mouse_divider_side = -1;
}
@ -1696,7 +1696,7 @@ App_Step_Sig(app_step){
}
}
else{
mouse_divider_vertical = 1;
mouse_divider_vertical = true;
if (mx > panel->inner.x0){
mouse_divider_side = -1;
}
@ -1706,15 +1706,14 @@ App_Step_Sig(app_step){
}
if (models->layout.panel_count > 1){
i32 which_child;
mouse_divider_id = panel->parent;
which_child = panel->which_child;
i32 which_child = panel->which_child;
for (;;){
Divider_And_ID div =layout_get_divider(&models->layout, mouse_divider_id);
if (which_child == mouse_divider_side &&
div.divider->v_divider == mouse_divider_vertical){
mouse_on_divider = 1;
mouse_on_divider = true;
break;
}
@ -1775,8 +1774,6 @@ App_Step_Sig(app_step){
cmd->key = null_key_event_data;
Temp_Memory param_stack_temp = begin_temp_memory(&models->mem.part);
if (input->first_step){
#if 0
@ -1887,12 +1884,9 @@ App_Step_Sig(app_step){
for (i32 i = 0; i < 128 && command_coroutine; ++i){
User_Input user_in = {0};
user_in.abort = 1;
user_in.abort = true;
command_coroutine =
app_resume_coroutine(system, &models->app_links, Co_Command,
command_coroutine, &user_in,
models->command_coroutine_flags);
command_coroutine = app_resume_coroutine(system, &models->app_links, Co_Command, command_coroutine, &user_in, models->command_coroutine_flags);
}
if (command_coroutine != 0){
// TODO(allen): post grave warning
@ -1970,35 +1964,33 @@ App_Step_Sig(app_step){
if (map == 0) map = &models->map_top;
Command_Binding cmd_bind = map_extract_recursive(map, key);
User_Input user_in;
User_Input user_in = {0};
user_in.type = UserInputKey;
user_in.key = key;
user_in.command.command = cmd_bind.custom;
user_in.abort = 0;
if ((EventOnEsc & abort_flags) && key.keycode == key_esc){
user_in.abort = 1;
user_in.abort = true;
}
else if (EventOnAnyKey & abort_flags){
user_in.abort = 1;
user_in.abort = true;
}
if (EventOnAnyKey & get_flags){
pass_in = 1;
pass_in = true;
consume_input(&vars->available_input, Input_AnyKey, "command coroutine");
}
if (key.keycode == key_esc){
if (EventOnEsc & get_flags){
pass_in = 1;
pass_in = true;
}
consume_input(&vars->available_input, Input_Esc, "command coroutine");
}
if (pass_in){
models->command_coroutine =
app_resume_coroutine(system, &models->app_links, Co_Command, command_coroutine, &user_in, models->command_coroutine_flags);
models->command_coroutine = app_resume_coroutine(system, &models->app_links, Co_Command, command_coroutine, &user_in, models->command_coroutine_flags);
app_result.animating = 1;
app_result.animating = true;
// TOOD(allen): Deduplicate
// TODO(allen): Should I somehow allow a view to clean up however it wants after a
@ -2017,55 +2009,52 @@ App_Step_Sig(app_step){
USE_VIEW(view);
b32 pass_in = 0;
User_Input user_in;
User_Input user_in = {0};
user_in.type = UserInputMouse;
user_in.mouse = input->mouse;
user_in.command.cmdid = 0;
user_in.abort = 0;
if (abort_flags & EventOnMouseMove){
user_in.abort = 1;
user_in.abort = true;
}
if (get_flags & EventOnMouseMove){
pass_in = 1;
pass_in = true;
consume_input(&vars->available_input, Input_MouseMove, "command coroutine");
}
if (input->mouse.press_l || input->mouse.release_l || input->mouse.l){
if (abort_flags & EventOnLeftButton){
user_in.abort = 1;
user_in.abort = true;
}
if (get_flags & EventOnLeftButton){
pass_in = 1;
pass_in = true;
consume_input(&vars->available_input, Input_MouseLeftButton, "command coroutine");
}
}
if (input->mouse.press_r || input->mouse.release_r || input->mouse.r){
if (abort_flags & EventOnRightButton){
user_in.abort = 1;
user_in.abort = true;
}
if (get_flags & EventOnRightButton){
pass_in = 1;
pass_in = true;
consume_input(&vars->available_input, Input_MouseRightButton, "command coroutine");
}
}
if (input->mouse.wheel != 0){
if (abort_flags & EventOnWheel){
user_in.abort = 1;
user_in.abort = true;
}
if (get_flags & EventOnWheel){
pass_in = 1;
pass_in = true;
consume_input(&vars->available_input, Input_MouseWheel, "command coroutine");
}
}
if (pass_in){
models->command_coroutine =
app_resume_coroutine(system, &models->app_links, Co_Command, command_coroutine, &user_in, models->command_coroutine_flags);
models->command_coroutine = app_resume_coroutine(system, &models->app_links, Co_Command, command_coroutine, &user_in, models->command_coroutine_flags);
app_result.animating = 1;
app_result.animating = true;
// TOOD(allen): Deduplicate
// TODO(allen): Should I somehow allow a view to clean up however it wants after a
@ -2514,10 +2503,30 @@ App_Step_Sig(app_step){
}
if (mouse_in_edit_area && mouse_panel != 0 && input->mouse.press_l){
models->layout.active_panel = (i32)(mouse_panel - models->layout.panels);
}
i32 new_panel_id = (i32)(mouse_panel - models->layout.panels);
if (models->layout.active_panel != new_panel_id){
if (models->command_coroutine != 0){
User_Input user_in = {0};
user_in.abort = true;
end_temp_memory(param_stack_temp);
for (u32 j = 0; j < 10 && models->command_coroutine != 0; ++j){
models->command_coroutine = app_resume_coroutine(system, &models->app_links, Co_Command, models->command_coroutine, &user_in, models->command_coroutine_flags);
}
if (models->command_coroutine != 0){
// TODO(allen): post grave warning
models->command_coroutine = 0;
}
Panel *active_panel = &models->layout.panels[models->layout.active_panel];
View *view = active_panel->view;
init_query_set(&view->query_set);
}
models->layout.active_panel = new_panel_id;
app_result.animating = true;
}
}
// NOTE(allen): on the first frame there should be no scrolling
if (input->first_step){

View File

@ -514,10 +514,9 @@ DOC_SEE(Buffer_ID)
Command_Data *cmd = (Command_Data*)app->cmd_context;
Working_Set *working_set = &cmd->models->working_set;
Buffer_Summary buffer = {};
Editing_File *file;
file = working_set_get_active_file(working_set, buffer_id);
if (file){
Editing_File *file = working_set_get_active_file(working_set, buffer_id);
if (file != 0){
fill_buffer_summary(&buffer, file, working_set);
if (!access_test(buffer.lock_flags, access)){
buffer = null_buffer_summary;
@ -539,11 +538,9 @@ DOC_SEE(Access_Flag)
*/{
Command_Data *cmd = (Command_Data*)app->cmd_context;
Buffer_Summary buffer = {};
Editing_File *file;
Working_Set *working_set = &cmd->models->working_set;
String str = make_string(name, len);
file = working_set_name_contains(working_set, str);
Editing_File *file = working_set_name_contains(working_set, make_string(name, len));
if (file && !file->is_dummy){
fill_buffer_summary(&buffer, file, working_set);
if (!access_test(buffer.lock_flags, access)){
@ -728,6 +725,18 @@ DOC_SEE(Marker)
return(result);
}
API_EXPORT Buffer_Summary
Get_Buffer_By_Marker_Handle(Application_Links *app, Marker_Handle marker, Access_Flag access)
/*
DOC_PARAM(marker, The marker handle to query.)
DOC_PARAM(access, The access parameter determines what levels of protection this call can access.)
DOC_SEE(Marker)
*/{
Buffer_ID buffer_id = get_buffer_id_from_marker_handle(marker);
Buffer_Summary buffer = Get_Buffer(app, buffer_id, access);
return(buffer);
}
API_EXPORT bool32
Buffer_Set_Markers(Application_Links *app, Buffer_Summary *buffer, Marker_Handle marker, uint32_t first_marker_index, uint32_t marker_count, Marker *source_markers)
/*
@ -817,6 +826,7 @@ DOC_RETURN(returns non-zero on success)
result = 1;
switch (setting){
case BufferSetting_Lex: *value_out = file->settings.tokens_exist; break;
case BufferSetting_LexWithoutStrings: *value_out = file->settings.tokens_without_strings; break;
case BufferSetting_WrapLine: *value_out = !file->settings.unwrapped_lines; break;
case BufferSetting_WrapPosition: *value_out = file->settings.display_width; break;
case BufferSetting_MinimumBaseWrapPosition: *value_out = file->settings.minimum_base_display_width; break;
@ -845,12 +855,12 @@ DOC_SEE(Buffer_Setting_ID)
Models *models = cmd->models;
Editing_File *file = imp_get_file(cmd, buffer);
bool32 result = 0;
bool32 result = false;
i32 new_mapid = 0;
if (file){
result = 11;
if (file != 0){
result = true;
switch (setting){
case BufferSetting_Lex:
{
@ -871,6 +881,25 @@ DOC_SEE(Buffer_Setting_ID)
}
}break;
case BufferSetting_LexWithoutStrings:
{
if (file->settings.tokens_exist){
if ((b8)value != file->settings.tokens_without_strings){
file_kill_tokens(system, &models->mem.general, file);
file->settings.tokens_without_strings = (b8)value;
if (!file->settings.virtual_white){
file_first_lex_parallel(system, &models->mem, file);
}
else{
file_first_lex_serial(&models->mem, file);
}
}
}
else{
file->settings.tokens_without_strings = (b8)value;
}
}break;
case BufferSetting_WrapLine:
{
file->settings.unwrapped_lines = !value;
@ -2267,17 +2296,21 @@ DOC(After this call the file list passed in should not be read or written to.)
}
API_EXPORT void
Set_GUI_Up_Down_Keys(Application_Links *app, int16_t up_key, int16_t down_key)
Set_GUI_Up_Down_Keys(Application_Links *app, Key_Code up_key, Key_Modifier up_key_modifier, Key_Code down_key, Key_Modifier down_key_modifier)
/*
DOC_PARAM(up_key, the code of the key that should be interpreted as an up key)
DOC_PARAM(up_key_modifier, the modifier for the key that should be interpreted as an up key)
DOC_PARAM(down_key, the code of the key that should be interpreted as a down key)
DOC_PARAM(down_key_modifier, the modifier for the key that should be interpreted as a down key)
DOC(This is a temporary ad-hoc solution to allow some customization of the behavior of the built in GUI. There is a high chance that it will be removed and not replaced at some point, so it is not recommended that it be heavily used.) */
{
Command_Data *cmd = (Command_Data*)app->cmd_context;
Models *models = cmd->models;
models->user_up_key = up_key;
models->user_up_key_modifier = up_key_modifier;
models->user_down_key = down_key;
models->user_down_key_modifier = down_key_modifier;
}
API_EXPORT void*

View File

@ -91,6 +91,8 @@ struct Models{
Key_Code user_up_key;
Key_Code user_down_key;
Key_Modifier user_up_key_modifier;
Key_Modifier user_down_key_modifier;
};
// BOTTOM

View File

@ -64,7 +64,7 @@ struct Text_Effect{
//
union Buffer_Slot_ID{
i32 id;
Buffer_ID id;
i16 part[2];
};
inline Buffer_Slot_ID
@ -98,11 +98,12 @@ struct Editing_File_Settings{
Font_ID font_id;
b8 unwrapped_lines;
b8 tokens_exist;
b8 tokens_without_strings;
b8 is_initialized;
b8 unimportant;
b8 read_only;
b8 never_kill;
u8 pad[2];
u8 pad[1];
};
global_const Editing_File_Settings null_editing_file_settings = {0};
@ -229,6 +230,13 @@ allocate_markers_state(General_Memory *general, Editing_File *file, u32 new_arra
return(array);
}
internal Buffer_ID
get_buffer_id_from_marker_handle(void *handle){
Marker_Array *markers = (Marker_Array*)handle;
Buffer_Slot_ID result = markers->buffer_id;
return(result.id);
}
internal b32
markers_set(Editing_File *file, void *handle, u32 first_index, u32 count, Marker *source){
Assert(file != 0);

View File

@ -2147,7 +2147,7 @@ Job_Callback_Sig(job_full_lex){
b32 still_lexing = 1;
Cpp_Lex_Data lex = cpp_lex_data_init();
Cpp_Lex_Data lex = cpp_lex_data_init(file->settings.tokens_without_strings);
// TODO(allen): deduplicate this against relex
char *chunks[3];
@ -2289,7 +2289,7 @@ file_first_lex_serial(Mem_Options *mem, Editing_File *file){
b32 still_lexing = 1;
Cpp_Lex_Data lex = cpp_lex_data_init();
Cpp_Lex_Data lex = cpp_lex_data_init(file->settings.tokens_without_strings);
// TODO(allen): deduplicate this against relex
char *chunks[3];
@ -2398,7 +2398,7 @@ file_relex_parallel(System_Functions *system, Mem_Options *mem, Editing_File *fi
i32 size = buffer_size(buffer);
Cpp_Relex_Data state = cpp_relex_init(array, start_i, end_i, shift_amount);
Cpp_Relex_Data state = cpp_relex_init(array, start_i, end_i, shift_amount, file->settings.tokens_without_strings);
char *chunks[3];
i32 chunk_sizes[3];
@ -2518,7 +2518,7 @@ file_relex_serial(Mem_Options *mem, Editing_File *file, i32 start_i, i32 end_i,
i32 size = buffer_size(buffer);
Cpp_Relex_Data state = cpp_relex_init(array, start_i, end_i, shift_amount);
Cpp_Relex_Data state = cpp_relex_init(array, start_i, end_i, shift_amount, file->settings.tokens_without_strings);
char *chunks[3];
i32 chunk_sizes[3];
@ -4908,6 +4908,8 @@ step_file_view(System_Functions *system, View *view, View *active_view, Input_Su
Key_Code user_up_key = models->user_up_key;
Key_Code user_down_key = models->user_down_key;
Key_Modifier user_up_key_modifier = models->user_up_key_modifier;
Key_Modifier user_down_key_modifier = models->user_down_key_modifier;
switch (view->interaction){
case IInt_Sys_File_List:
@ -4966,7 +4968,7 @@ step_file_view(System_Functions *system, View *view, View *active_view, Input_Su
if (gui_begin_list(target, id, view->list_i, 0, snap_into_view, &update)){
// TODO(allen): Allow me to handle key consumption correctly here!
gui_standard_list(target, id, &view->gui_scroll, view->scroll_region, &keys, &view->list_i, &update, user_up_key, user_down_key);
gui_standard_list(target, id, &view->gui_scroll, view->scroll_region, &keys, &view->list_i, &update, user_up_key, user_up_key_modifier, user_down_key, user_down_key_modifier);
}
b32 do_new_directory = false;
@ -5063,7 +5065,7 @@ step_file_view(System_Functions *system, View *view, View *active_view, Input_Su
id.id[0] = (u64)(working_set) + 1;
if (gui_begin_list(target, id, view->list_i, 0, snap_into_view, &update)){
gui_standard_list(target, id, &view->gui_scroll, view->scroll_region, &keys, &view->list_i, &update, user_up_key, user_down_key);
gui_standard_list(target, id, &view->gui_scroll, view->scroll_region, &keys, &view->list_i, &update, user_up_key, user_up_key_modifier, user_down_key, user_down_key_modifier);
}
{
@ -5648,21 +5650,13 @@ struct Input_Process_Result{
i32 max_y;
};
static char
to_writable_char(Key_Code long_character){
char character = 0;
if (long_character < ' '){
if (long_character == '\n'){
character = '\n';
}
else if (long_character == '\t'){
character = '\t';
}
static u32
to_writable_character(Key_Code long_character, u8 *character){
u32 result = 0;
if (long_character != 0){
u32_to_utf8_unchecked(long_character, character, &result);
}
else if (long_character >= ' ' && long_character <= 255 && long_character != 127){
character = (char)long_character;
}
return(character);
return(result);
}
internal Input_Process_Result
@ -5775,11 +5769,15 @@ do_step_file_view(System_Functions *system, View *view, i32_Rect rect, b32 is_ac
i32 count = keys->count;
for (i32 i = 0; i < count; ++i){
Key_Event_Data key = get_single_key(keys, i);
char character = to_writable_char(key.character);
if (char_to_upper(character) == activation_key){
target->active = b->id;
result.is_animating = 1;
break;
u8 character[4];
u32 length = to_writable_character(key.character, character);
if (length == 1){
if (char_to_upper(character[0]) == activation_key){
target->active = b->id;
result.is_animating = 1;
break;
}
}
}
}

View File

@ -1254,31 +1254,50 @@ gui_do_jump(GUI_Target *target, GUI_View_Jump jump, GUI_Scroll_Vars vars){
}
internal void
gui_standard_list(GUI_Target *target, GUI_id id, GUI_Scroll_Vars *vars, i32_Rect scroll_region, Key_Input_Data *keys, i32 *list_i, GUI_Item_Update *update, Key_Code user_up_key, Key_Code user_down_key){
gui_standard_list(GUI_Target *target, GUI_id id, GUI_Scroll_Vars *vars, i32_Rect scroll_region, Key_Input_Data *keys, i32 *list_i, GUI_Item_Update *update, Key_Code user_up_key, Key_Modifier user_up_key_modifier, Key_Code user_down_key, Key_Modifier user_down_key_modifier){
if (update->has_adjustment){
*list_i = update->adjustment_value;
}
if (update->has_index_position){
GUI_View_Jump jump =
gui_compute_view_jump(scroll_region, update->index_position);
GUI_View_Jump jump = gui_compute_view_jump(scroll_region, update->index_position);
jump.view_min = jump.view_min + 45;
jump.view_max = jump.view_max - 45;
*vars = gui_do_jump(target, jump, *vars);
}
i8 modifiers_up[3];
modifiers_up[0] = ((user_up_key_modifier & MDFR_CTRL) != 0);
modifiers_up[1] = ((user_up_key_modifier & MDFR_ALT) != 0);
modifiers_up[2] = ((user_up_key_modifier & MDFR_SHIFT) != 0);
i8 modifiers_down[3];
modifiers_down[0] = ((user_down_key_modifier & MDFR_CTRL) != 0);
modifiers_down[1] = ((user_down_key_modifier & MDFR_ALT) != 0);
modifiers_down[2] = ((user_down_key_modifier & MDFR_SHIFT) != 0);
b32 indirectly_activate = 0;
for (i32 j = 0; j < keys->count; ++j){
Key_Code key = keys->keys[j].keycode;
Key_Event_Data key = keys->keys[j];
b32 modifiers_match_up = false;
b32 modifiers_match_down = false;
if (key == user_up_key){
if (modifiers_up[0] == key.modifiers[MDFR_CONTROL_INDEX] && modifiers_up[1] == key.modifiers[MDFR_ALT_INDEX] && modifiers_up[2] == key.modifiers[MDFR_SHIFT_INDEX]){
modifiers_match_up = true;
}
if (modifiers_down[0] == key.modifiers[MDFR_CONTROL_INDEX] && modifiers_down[1] == key.modifiers[MDFR_ALT_INDEX] && modifiers_down[2] == key.modifiers[MDFR_SHIFT_INDEX]){
modifiers_match_down = true;
}
if (key.keycode == user_up_key && modifiers_match_up){
--*list_i;
}
else if (key == user_down_key){
else if (key.keycode == user_down_key && modifiers_match_down){
++*list_i;
}
else if (key == '\n' || key == '\t'){
else if (key.keycode == '\n' || key.keycode == '\t'){
indirectly_activate = 1;
}
}

Binary file not shown.

View File

@ -11,6 +11,8 @@
#include <stdio.h>
#include <stdint.h>
typedef int32_t bool32;
#define Assert(n) do{ if (!(n)) { *(int*)0 = 0xA11E; } }while(0)
#define ArrayCount(a) (sizeof(a)/sizeof(*a))
@ -100,7 +102,7 @@ int_fsm(Cpp_Lex_FSM fsm, char c){
}
Cpp_Lex_FSM
main_fsm(Cpp_Lex_FSM fsm, uint8_t pp_state, uint8_t c){
main_fsm(Cpp_Lex_FSM fsm, uint8_t pp_state, uint8_t c, bool32 ignore_string_delims){
if (c == 0){
fsm.emit_token = 1;
}
@ -125,15 +127,32 @@ main_fsm(Cpp_Lex_FSM fsm, uint8_t pp_state, uint8_t c){
}
else{
switch (c){
case '\'': fsm.state = LS_char; break;
case '"': fsm.state = LS_string; break;
case '\'':
{
if (ignore_string_delims){
fsm.state = LS_identifier;
}
else{
fsm.state = LS_char;
}
}break;
case '"':
{
if (ignore_string_delims){
fsm.state = LS_identifier;
}
else{
fsm.state = LS_string;
}
}break;
case '/': fsm.state = LS_comment_pre; break;
case '.': fsm.state = LS_dot; break;
case '<':
if (pp_state == LSPP_include){
if (pp_state == LSPP_include && !ignore_string_delims){
fsm.state = LS_string;
}
else{
@ -193,7 +212,8 @@ main_fsm(Cpp_Lex_FSM fsm, uint8_t pp_state, uint8_t c){
case LS_identifier:
{
int is_ident = (c >= '0' && c <= '9') || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_' || c == '$' || c >= 128;
int is_ident = (c >= '0' && c <= '9') || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_' || c == '$' || c >= 128 || (ignore_string_delims && (c == '\'' || c == '"'));
if (!is_ident){
fsm.emit_token = 1;
}
@ -210,7 +230,7 @@ main_fsm(Cpp_Lex_FSM fsm, uint8_t pp_state, uint8_t c){
if (c == ' ' || c == '\r' || c == '\v' || c == '\f'){
// NOTE(allen): do nothing
}
else if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c >= 128){
else if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c >= 128 || (ignore_string_delims && (c == '\'' || c == '"'))){
fsm.state = LS_ppdef;
}
else{
@ -220,47 +240,75 @@ main_fsm(Cpp_Lex_FSM fsm, uint8_t pp_state, uint8_t c){
case LS_ppdef:
{
int is_ident = (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c >= 128;
int is_ident = (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c >= 128 || (ignore_string_delims && (c == '\'' || c == '"'));
if (!is_ident){
fsm.emit_token = 1;
}
}break;
case LS_char: case LS_char_multiline:
switch(c){
case '\n': case '\'': fsm.emit_token = 1; break;
case '\\': fsm.state = LS_char_slashed; break;
}
break;
{
if (ignore_string_delims){
fsm.state = LS_string;
fsm.emit_token = 1;
}
else{
switch(c){
case '\n': case '\'': fsm.emit_token = 1; break;
case '\\': fsm.state = LS_char_slashed; break;
}
}
}break;
case LS_char_slashed:
switch (c){
case '\r': case '\f': case '\v': break;
case '\n': fsm.state = LS_char_multiline; break;
default: fsm.state = LS_char; break;
}
break;
{
if (ignore_string_delims){
fsm.state = LS_string;
fsm.emit_token = 1;
}
else{
switch (c){
case '\r': case '\f': case '\v': break;
case '\n': fsm.state = LS_char_multiline; break;
default: fsm.state = LS_char; break;
}
}
}break;
case LS_string:
case LS_string_multiline:
switch(c){
case '\n': case '\"': fsm.emit_token = 1; break;
case '>':
if (pp_state == LSPP_include){
{
if (ignore_string_delims){
fsm.state = LS_string;
fsm.emit_token = 1;
}
break;
case '\\': fsm.state = LS_string_slashed; break;
}
break;
else{
switch(c){
case '\n': case '"': fsm.emit_token = 1; break;
case '>':
if (pp_state == LSPP_include){
fsm.emit_token = 1;
}
break;
case '\\': fsm.state = LS_string_slashed; break;
}
}
}break;
case LS_string_slashed:
switch (c){
case '\r': case '\f': case '\v': break;
case '\n': fsm.state = LS_string_multiline; break;
default: fsm.state = LS_string; break;
}
break;
{
if (ignore_string_delims){
fsm.state = LS_string;
fsm.emit_token = 1;
}
else{
switch (c){
case '\r': case '\f': case '\v': break;
case '\n': fsm.state = LS_string_multiline; break;
default: fsm.state = LS_string; break;
}
}
}break;
case LS_number:
if (c >= '0' && c <= '9'){
@ -633,7 +681,7 @@ generate_int_table(){
}
static FSM_Tables
generate_fsm_table(uint8_t pp_state){
generate_fsm_table(uint8_t pp_state, bool32 ignore_string_delims){
uint8_t state_count = LS_count;
FSM_Tables table;
allocate_full_tables(&table, state_count);
@ -645,7 +693,7 @@ generate_fsm_table(uint8_t pp_state){
for (uint8_t state = 0; state < state_count; ++state){
fsm.state = state;
fsm.emit_token = 0;
new_fsm = main_fsm(fsm, pp_state, (uint8_t)c);
new_fsm = main_fsm(fsm, pp_state, (uint8_t)c, ignore_string_delims);
table.full_transition_table[i++] = new_fsm.state + state_count*new_fsm.emit_token;
}
}
@ -690,24 +738,25 @@ render_comment(FILE *file, char *comment){
typedef struct PP_Names{
uint8_t pp_state;
char *name;
bool32 ignore_string_delims;
} PP_Names;
static PP_Names pp_names[] = {
{LSPP_default, "main_fsm"},
{LSPP_include, "pp_include_fsm"},
{LSPP_macro_identifier, "pp_macro_fsm"},
{LSPP_identifier, "pp_identifier_fsm"},
{LSPP_body_if, "pp_body_if_fsm"},
{LSPP_body, "pp_body_fsm"},
{LSPP_number, "pp_number_fsm"},
{LSPP_error, "pp_error_fsm"},
{LSPP_junk, "pp_junk_fsm"},
{LSPP_default, "main_fsm", false},
{LSPP_include, "pp_include_fsm", false},
{LSPP_macro_identifier, "pp_macro_fsm", false},
{LSPP_identifier, "pp_identifier_fsm", false},
{LSPP_body_if, "pp_body_if_fsm", false},
{LSPP_body, "pp_body_fsm", false},
{LSPP_number, "pp_number_fsm", false},
{LSPP_error, "pp_error_fsm", false},
{LSPP_junk, "pp_junk_fsm", false},
{LSPP_default, "no_string_fsm", true},
};
int
main(){
FILE *file;
file = fopen(LEXER_TABLE_FILE, "wb");
FILE *file = fopen(LEXER_TABLE_FILE, "wb");
FSM_Tables wtables = generate_whitespace_skip_table();
render_fsm_table(file, wtables, "whitespace_fsm");
@ -723,8 +772,7 @@ main(){
end_table(file);
for (int32_t i = 0; i < ArrayCount(pp_names); ++i){
Assert(i == pp_names[i].pp_state);
FSM_Tables tables = generate_fsm_table(pp_names[i].pp_state);
FSM_Tables tables = generate_fsm_table(pp_names[i].pp_state, pp_names[i].ignore_string_delims);
render_fsm_table(file, tables, pp_names[i].name);
}

View File

@ -9,8 +9,11 @@ TYPE: 'build-target'
#if !defined(FCODER_EXPERIMENTS_CPP)
#define FCODER_EXPERIMENTS_CPP
#define FCODER_JUMP_COMMANDS
#include "4coder_default_include.cpp"
#include "4coder_miblo_numbers.cpp"
#undef FCODER_JUMP_COMMANDS
#include "4coder_sticky_jump.cpp"
#define NO_BINDING
#include "4coder_default_bindings.cpp"

View File

@ -0,0 +1,518 @@
/*
4coder_sticky_jump.cpp - Commands and helpers for parsing jump locations from
compiler errors, sticking markers on jump locations, and jumping to them.
TYPE: 'drop-in-command-pack'
*/
// TOP
#if !defined(FCODER_STICKY_JUMP) && !defined(FCODER_JUMP_COMMANDS)
#define FCODER_STICKY_JUMP
#define FCODER_JUMP_COMMANDS
#include "4coder_default_framework.h"
#include "4coder_helper/4coder_long_seek.h"
#include "4coder_helper/4coder_helper.h"
#include "4coder_helper/4coder_jump_parsing.h"
#include "4coder_lib/4coder_mem.h"
#include "4coder_jumping.h"
static uint32_t
binary_search(uint32_t *array, uint32_t count, uint32_t x){
uint32_t i = 0;
uint32_t first = 0;
uint32_t last = count;
if (first < last){
for (;;){
i = (first + last)/2;
if (array[i] < x){
first = i;
}
else if (array[i] > x){
last = i;
}
else{ // NOTE(allen): array[i] == x
break;
}
if (first+1 >= last){
i = first;
break;
}
}
}
return(i);
}
struct Marker_List{
uint32_t *handle_starts;
Marker_Handle *handles;
uint32_t *jump_line_numbers;
uint32_t handle_count;
uint32_t handle_max;
int32_t jump_max;
int32_t jump_count;
};
static void
double_jump_max(General_Memory *general, Marker_List *list){
uint32_t new_jump_max = list->jump_max*2;
list->jump_line_numbers = gen_realloc_array(general, uint32_t, list->jump_line_numbers, list->jump_max, new_jump_max);
list->jump_max = new_jump_max;
}
static void
double_handle_max(General_Memory *general, Marker_List *list){
uint32_t new_handle_max = list->handle_max*2;
list->handle_starts = gen_realloc_array(general, uint32_t, list->handle_starts, list->handle_max, new_handle_max);
list->handles = gen_realloc_array(general, Marker_Handle, list->handles, list->handle_max, new_handle_max);
list->handle_max = new_handle_max;
}
// TODO(allen): what to do when a push returns 0?
static Marker_List
make_marker_list(Application_Links *app, Partition *part, General_Memory *general, int32_t buffer_id){
Marker_List list = {0};
int32_t line = 1;
Temp_Memory temp = begin_temp_memory(part);
ID_Based_Jump_Location *location_list = (ID_Based_Jump_Location*)partition_current(part);
uint32_t location_count = 0;
list.handle_max = 64;
list.handle_starts = gen_array(general, uint32_t, list.handle_max);
list.handles = gen_array(general, Marker_Handle, list.handle_max);
list.jump_max = 64;
list.jump_line_numbers = gen_array(general, uint32_t, list.jump_max);
uint32_t prev_jump_count = 0;
for (;;){
int32_t this_jump_line = 0;
int32_t colon_index = 0;
Name_Based_Jump_Location location = {0};
Temp_Memory temp_name = begin_temp_memory(part);
if (seek_next_jump_in_buffer(app, part, buffer_id, line, false, 1, &this_jump_line, &colon_index, &location)){
Buffer_Summary jump_buffer = {0};
if (open_file(app, &jump_buffer, location.file.str, location.file.size, false, true)){
ID_Based_Jump_Location id_location = {0};
end_temp_memory(temp_name);
id_location.buffer_id = jump_buffer.buffer_id;
id_location.line = location.line;
id_location.column = location.column;
if (id_location.buffer_id != 0){
if (location_count > 0){
ID_Based_Jump_Location *prev_location = &location_list[location_count-1];
if (prev_location->buffer_id != id_location.buffer_id){
Buffer_Summary location_buffer = get_buffer(app, prev_location->buffer_id, AccessAll);
if (location_buffer.exists){
if (list.handle_count >= list.handle_max){
double_handle_max(general, &list);
}
Marker_Handle new_handle = buffer_add_markers(app, &location_buffer, location_count);
list.handle_starts[list.handle_count] = prev_jump_count;
list.handles[list.handle_count] = new_handle;
++list.handle_count;
prev_jump_count = list.jump_count;
Marker *markers = push_array(part, Marker, location_count);
for (uint32_t i = 0; i < location_count; ++i){
ID_Based_Jump_Location *location = &location_list[i];
Partial_Cursor cursor = {0};
Buffer_Seek seek = seek_line_char(location->line, location->column);
if (buffer_compute_cursor(app, &location_buffer, seek, &cursor)){
markers[i].pos = cursor.pos;
markers[i].lean_right = false;
}
}
buffer_set_markers(app, &location_buffer, new_handle, 0, location_count, markers);
location_count = 0;
reset_temp_memory(temp);
}
}
}
ID_Based_Jump_Location *new_id_location = push_struct(part, ID_Based_Jump_Location);
*new_id_location = id_location;
++location_count;
if (list.jump_count >= list.jump_max){
double_jump_max(general, &list);
}
list.jump_line_numbers[list.jump_count] = this_jump_line;
++list.jump_count;
}
}
else{
end_temp_memory(temp_name);
}
line = this_jump_line+1;
}
else{
end_temp_memory(temp_name);
break;
}
}
if (location_count > 0){
ID_Based_Jump_Location *prev_location = &location_list[location_count-1];
Buffer_Summary location_buffer = get_buffer(app, prev_location->buffer_id, AccessAll);
if (list.handle_count >= list.handle_max){
double_handle_max(general, &list);
}
Marker_Handle new_handle = buffer_add_markers(app, &location_buffer, location_count);
list.handle_starts[list.handle_count] = prev_jump_count;
list.handles[list.handle_count] = new_handle;
++list.handle_count;
prev_jump_count = list.jump_count;
Marker *markers = push_array(part, Marker, location_count);
for (uint32_t i = 0; i < location_count; ++i){
ID_Based_Jump_Location *location = &location_list[i];
Partial_Cursor cursor = {0};
Buffer_Seek seek = seek_line_char(location->line, location->column);
if (buffer_compute_cursor(app, &location_buffer, seek, &cursor)){
markers[i].pos = cursor.pos;
markers[i].lean_right = false;
}
}
buffer_set_markers(app, &location_buffer, new_handle, 0, location_count, markers);
location_count = 0;
reset_temp_memory(temp);
}
end_temp_memory(temp);
return(list);
}
static void
free_marker_list(General_Memory *general, Marker_List list){
general_memory_free(general, list.handle_starts);
general_memory_free(general, list.handles);
general_memory_free(general, list.jump_line_numbers);
}
struct Marker_List_Slot{
Marker_List list;
int32_t buffer_id;
};
static Marker_List_Slot *marker_list_slots = 0;
static uint32_t marker_list_slot_count = 0;
static uint32_t marker_list_slot_max = 0;
static Marker_List*
set_marker_list_for_buffer(int32_t buffer_id, Marker_List *list){
Marker_List *result = 0;
General_Memory *general = &global_general;
bool32 found_slot = false;
for (uint32_t i = 0; i < marker_list_slot_count; ++i){
if (buffer_id == marker_list_slots[i].buffer_id){
if (list != 0){
marker_list_slots[i].list = *list;
result = &marker_list_slots[i].list;
}
else{
void *dst = marker_list_slots+i;
void *src = marker_list_slots+i+1;
size_t amount = (marker_list_slot_count-i-1)*sizeof(Marker_List_Slot);
memmove(dst, src, amount);
--marker_list_slot_count;
}
found_slot = true;
break;
}
}
if (!found_slot && list != 0){
if (marker_list_slot_count >= marker_list_slot_max){
if (marker_list_slots == 0){
uint32_t new_max = 64;
marker_list_slots = gen_array(general, Marker_List_Slot, new_max);
marker_list_slot_max = new_max;
}
else{
uint32_t new_max = 2*marker_list_slot_max;
marker_list_slots = gen_realloc_array(general, Marker_List_Slot, marker_list_slots, marker_list_slot_count, new_max);
marker_list_slot_max = new_max;
}
}
marker_list_slots[marker_list_slot_count].buffer_id = buffer_id;
marker_list_slots[marker_list_slot_count].list = *list;
result = &marker_list_slots[marker_list_slot_count].list;
++marker_list_slot_count;
}
return(result);
}
static Marker_List*
get_marker_list_for_buffer(int32_t buffer_id){
Marker_List *result = 0;
for (uint32_t i = 0; i < marker_list_slot_count; ++i){
if (buffer_id == marker_list_slots[i].buffer_id){
result = &marker_list_slots[i].list;
break;
}
}
return(result);
}
static Marker_List*
get_or_make_list_for_buffer(Application_Links *app, Partition *part, General_Memory *general, int32_t buffer_id){
Marker_List *result = get_marker_list_for_buffer(buffer_id);
if (result == 0){
Marker_List new_list = make_marker_list(app, part, general, buffer_id);
result = set_marker_list_for_buffer(buffer_id, &new_list);
}
return(result);
}
static bool32
get_jump_from_list(Application_Links *app, Marker_List *list, int32_t index, ID_Pos_Jump_Location *location){
bool32 result = false;
if (index >= 0 && index < list->jump_count){
uint32_t handle_index = binary_search(list->handle_starts, list->handle_count, index);
uint32_t handle_start = list->handle_starts[handle_index];
uint32_t marker_index = index - handle_start;
Marker_Handle handle = list->handles[handle_index];
Buffer_Summary buffer = get_buffer_by_marker_handle(app, handle, AccessAll);
if (buffer.exists){
Marker marker;
buffer_get_markers(app, &buffer, handle, marker_index, 1, &marker);
location->buffer_id = buffer.buffer_id;
location->pos = marker.pos;
result = true;
}
}
return(result);
}
static int32_t
get_index_exact_from_list(Marker_List *list, int32_t line){
int32_t result = -1;
uint32_t jump_index = binary_search(list->jump_line_numbers, list->jump_count, line);
if (list->jump_line_numbers[jump_index] == (uint32_t)line){
result = jump_index;
}
return(result);
}
static int32_t
get_index_nearest_from_list(Marker_List *list, int32_t line){
int32_t result = binary_search(list->jump_line_numbers, list->jump_count, line);
return(result);
}
static int32_t
get_line_from_list(Marker_List *list, int32_t index){
int32_t result = 0;
if (index >= 0 && index < list->jump_count){
result = list->jump_line_numbers[index];
}
return(result);
}
CUSTOM_COMMAND_SIG(goto_jump_at_cursor){
General_Memory *general = &global_general;
Partition *part = &global_part;
Temp_Memory temp = begin_temp_memory(part);
View_Summary view = get_active_view(app, AccessProtected);
Marker_List *list = get_or_make_list_for_buffer(app, part, general, view.buffer_id);
int32_t list_index = get_index_exact_from_list(list, view.cursor.line);
if (list_index >= 0){
ID_Pos_Jump_Location location = {0};
if (get_jump_from_list(app, list, list_index, &location)){
Buffer_Summary buffer = {0};
if (get_jump_buffer(app, &buffer, &location)){
change_active_panel(app);
View_Summary target_view = get_active_view(app, AccessAll);
switch_to_existing_view(app, &target_view, &buffer);
jump_to_location(app, &target_view, &buffer, location);
}
}
}
end_temp_memory(temp);
}
CUSTOM_COMMAND_SIG(goto_jump_at_cursor_same_panel){
General_Memory *general = &global_general;
Partition *part = &global_part;
Temp_Memory temp = begin_temp_memory(part);
View_Summary view = get_active_view(app, AccessProtected);
Marker_List *list = get_or_make_list_for_buffer(app, part, general, view.buffer_id);
int32_t list_index = get_index_exact_from_list(list, view.cursor.line);
if (list_index >= 0){
ID_Pos_Jump_Location location = {0};
if (get_jump_from_list(app, list, list_index, &location)){
Buffer_Summary buffer = {0};
if (get_jump_buffer(app, &buffer, &location)){
View_Summary target_view = view;
jump_to_location(app, &target_view, &buffer, location);
}
}
}
end_temp_memory(temp);
}
// TODO(allen): MASSIVELY DEDUPLICATE THIS PLEASE.
CUSTOM_COMMAND_SIG(goto_next_jump){
General_Memory *general = &global_general;
Partition *part = &global_part;
View_Summary view = get_view_for_locked_jump_buffer(app);
if (view.exists){
Marker_List *list = get_or_make_list_for_buffer(app, part, general, view.buffer_id);
int32_t list_index = get_index_nearest_from_list(list, view.cursor.line);
++list_index;
if (list_index >= 0 && list_index < list->jump_count){
ID_Pos_Jump_Location location = {0};
if (get_jump_from_list(app, list, list_index, &location)){
Buffer_Summary buffer = {0};
if (get_jump_buffer(app, &buffer, &location)){
View_Summary target_view = get_active_view(app, AccessAll);
if (target_view.view_id == view.view_id){
change_active_panel(app);
target_view = get_active_view(app, AccessAll);
}
switch_to_existing_view(app, &target_view, &buffer);
jump_to_location(app, &target_view, &buffer, location);
}
int32_t updated_line = get_line_from_list(list, list_index);
view_set_cursor(app, &view, seek_line_char(updated_line, 1), true);
}
}
}
}
CUSTOM_COMMAND_SIG(goto_prev_jump){
General_Memory *general = &global_general;
Partition *part = &global_part;
View_Summary view = get_view_for_locked_jump_buffer(app);
if (view.exists){
Marker_List *list = get_or_make_list_for_buffer(app, part, general, view.buffer_id);
int32_t list_index = get_index_nearest_from_list(list, view.cursor.line);
--list_index;
if (list_index >= 0 && list_index < list->jump_count){
ID_Pos_Jump_Location location = {0};
if (get_jump_from_list(app, list, list_index, &location)){
Buffer_Summary buffer = {0};
if (get_jump_buffer(app, &buffer, &location)){
View_Summary target_view = get_active_view(app, AccessAll);
if (target_view.view_id == view.view_id){
change_active_panel(app);
target_view = get_active_view(app, AccessAll);
}
switch_to_existing_view(app, &target_view, &buffer);
jump_to_location(app, &target_view, &buffer, location);
}
int32_t updated_line = get_line_from_list(list, list_index);
view_set_cursor(app, &view, seek_line_char(updated_line, 1), true);
}
}
}
}
CUSTOM_COMMAND_SIG(goto_first_jump){
General_Memory *general = &global_general;
Partition *part = &global_part;
View_Summary view = get_view_for_locked_jump_buffer(app);
if (view.exists){
Marker_List *list = get_or_make_list_for_buffer(app, part, general, view.buffer_id);
int32_t list_index = 0;
ID_Pos_Jump_Location location = {0};
if (get_jump_from_list(app, list, list_index, &location)){
Buffer_Summary buffer = {0};
if (get_jump_buffer(app, &buffer, &location)){
View_Summary target_view = get_active_view(app, AccessAll);
if (target_view.view_id == view.view_id){
change_active_panel(app);
target_view = get_active_view(app, AccessAll);
}
switch_to_existing_view(app, &target_view, &buffer);
jump_to_location(app, &target_view, &buffer, location);
}
int32_t updated_line = get_line_from_list(list, list_index);
view_set_cursor(app, &view, seek_line_char(updated_line, 1), true);
}
}
}
//
// Insert Newline or Tigger Jump on Read Only Buffer
//
CUSTOM_COMMAND_SIG(newline_or_goto_position){
View_Summary view = get_active_view(app, AccessProtected);
Buffer_Summary buffer = get_buffer(app, view.buffer_id, AccessProtected);
if (buffer.lock_flags & AccessProtected){
goto_jump_at_cursor(app);
lock_jump_buffer(buffer);
}
else{
write_character(app);
}
}
CUSTOM_COMMAND_SIG(newline_or_goto_position_same_panel){
View_Summary view = get_active_view(app, AccessProtected);
Buffer_Summary buffer = get_buffer(app, view.buffer_id, AccessProtected);
if (buffer.lock_flags & AccessProtected){
goto_jump_at_cursor_same_panel(app);
lock_jump_buffer(buffer);
}
else{
write_character(app);
}
}
#define goto_next_jump_no_skips goto_next_jump
#define goto_prev_jump_no_skips goto_prev_jump
#define seek_error seek_jump
#define goto_next_error goto_next_jump
#define goto_prev_error goto_prev_jump
#define goto_next_error_no_skips goto_next_jump_no_skips
#define goto_first_error goto_first_jump
#endif
// BOTTOM