got new lexer keywords thing working, built out several example 'languages' began investigating the jump to error situation.
parent
a4ef272b1b
commit
4d71a35fed
|
@ -5,6 +5,7 @@ struct Application_Links;
|
|||
#define CLIPBOARD_POST_SIG(n) void n(Application_Links *app, int32_t clipboard_id, char *str, int32_t len)
|
||||
#define CLIPBOARD_COUNT_SIG(n) int32_t n(Application_Links *app, int32_t clipboard_id)
|
||||
#define CLIPBOARD_INDEX_SIG(n) int32_t n(Application_Links *app, int32_t clipboard_id, int32_t item_index, char *out, int32_t len)
|
||||
#define CREATE_PARSE_CONTEXT_SIG(n) Parse_Context_ID n(Application_Links *app, Parser_String_And_Type *kw, uint32_t kw_count, Parser_String_And_Type *pp, uint32_t pp_count)
|
||||
#define GET_BUFFER_COUNT_SIG(n) int32_t n(Application_Links *app)
|
||||
#define GET_BUFFER_FIRST_SIG(n) Buffer_Summary n(Application_Links *app, Access_Flag access)
|
||||
#define GET_BUFFER_NEXT_SIG(n) void n(Application_Links *app, Buffer_Summary *buffer, Access_Flag access)
|
||||
|
@ -79,6 +80,7 @@ typedef EXEC_SYSTEM_COMMAND_SIG(Exec_System_Command_Function);
|
|||
typedef CLIPBOARD_POST_SIG(Clipboard_Post_Function);
|
||||
typedef CLIPBOARD_COUNT_SIG(Clipboard_Count_Function);
|
||||
typedef CLIPBOARD_INDEX_SIG(Clipboard_Index_Function);
|
||||
typedef CREATE_PARSE_CONTEXT_SIG(Create_Parse_Context_Function);
|
||||
typedef GET_BUFFER_COUNT_SIG(Get_Buffer_Count_Function);
|
||||
typedef GET_BUFFER_FIRST_SIG(Get_Buffer_First_Function);
|
||||
typedef GET_BUFFER_NEXT_SIG(Get_Buffer_Next_Function);
|
||||
|
@ -155,6 +157,7 @@ Exec_System_Command_Function *exec_system_command;
|
|||
Clipboard_Post_Function *clipboard_post;
|
||||
Clipboard_Count_Function *clipboard_count;
|
||||
Clipboard_Index_Function *clipboard_index;
|
||||
Create_Parse_Context_Function *create_parse_context;
|
||||
Get_Buffer_Count_Function *get_buffer_count;
|
||||
Get_Buffer_First_Function *get_buffer_first;
|
||||
Get_Buffer_Next_Function *get_buffer_next;
|
||||
|
@ -230,6 +233,7 @@ Exec_System_Command_Function *exec_system_command_;
|
|||
Clipboard_Post_Function *clipboard_post_;
|
||||
Clipboard_Count_Function *clipboard_count_;
|
||||
Clipboard_Index_Function *clipboard_index_;
|
||||
Create_Parse_Context_Function *create_parse_context_;
|
||||
Get_Buffer_Count_Function *get_buffer_count_;
|
||||
Get_Buffer_First_Function *get_buffer_first_;
|
||||
Get_Buffer_Next_Function *get_buffer_next_;
|
||||
|
@ -313,6 +317,7 @@ app_links->exec_system_command_ = Exec_System_Command;\
|
|||
app_links->clipboard_post_ = Clipboard_Post;\
|
||||
app_links->clipboard_count_ = Clipboard_Count;\
|
||||
app_links->clipboard_index_ = Clipboard_Index;\
|
||||
app_links->create_parse_context_ = Create_Parse_Context;\
|
||||
app_links->get_buffer_count_ = Get_Buffer_Count;\
|
||||
app_links->get_buffer_first_ = Get_Buffer_First;\
|
||||
app_links->get_buffer_next_ = Get_Buffer_Next;\
|
||||
|
@ -388,6 +393,7 @@ static inline bool32 exec_system_command(Application_Links *app, View_Summary *v
|
|||
static inline void clipboard_post(Application_Links *app, int32_t clipboard_id, char *str, int32_t len){(app->clipboard_post(app, clipboard_id, str, len));}
|
||||
static inline int32_t clipboard_count(Application_Links *app, int32_t clipboard_id){return(app->clipboard_count(app, clipboard_id));}
|
||||
static inline int32_t clipboard_index(Application_Links *app, int32_t clipboard_id, int32_t item_index, char *out, int32_t len){return(app->clipboard_index(app, clipboard_id, item_index, out, len));}
|
||||
static inline Parse_Context_ID create_parse_context(Application_Links *app, Parser_String_And_Type *kw, uint32_t kw_count, Parser_String_And_Type *pp, uint32_t pp_count){return(app->create_parse_context(app, kw, kw_count, pp, pp_count));}
|
||||
static inline int32_t get_buffer_count(Application_Links *app){return(app->get_buffer_count(app));}
|
||||
static inline Buffer_Summary get_buffer_first(Application_Links *app, Access_Flag access){return(app->get_buffer_first(app, access));}
|
||||
static inline void get_buffer_next(Application_Links *app, Buffer_Summary *buffer, Access_Flag access){(app->get_buffer_next(app, buffer, access));}
|
||||
|
@ -463,6 +469,7 @@ static inline bool32 exec_system_command(Application_Links *app, View_Summary *v
|
|||
static inline void clipboard_post(Application_Links *app, int32_t clipboard_id, char *str, int32_t len){(app->clipboard_post_(app, clipboard_id, str, len));}
|
||||
static inline int32_t clipboard_count(Application_Links *app, int32_t clipboard_id){return(app->clipboard_count_(app, clipboard_id));}
|
||||
static inline int32_t clipboard_index(Application_Links *app, int32_t clipboard_id, int32_t item_index, char *out, int32_t len){return(app->clipboard_index_(app, clipboard_id, item_index, out, len));}
|
||||
static inline Parse_Context_ID create_parse_context(Application_Links *app, Parser_String_And_Type *kw, uint32_t kw_count, Parser_String_And_Type *pp, uint32_t pp_count){return(app->create_parse_context_(app, kw, kw_count, pp, pp_count));}
|
||||
static inline int32_t get_buffer_count(Application_Links *app){return(app->get_buffer_count_(app));}
|
||||
static inline Buffer_Summary get_buffer_first(Application_Links *app, Access_Flag access){return(app->get_buffer_first_(app, access));}
|
||||
static inline void get_buffer_next(Application_Links *app, Buffer_Summary *buffer, Access_Flag access){(app->get_buffer_next_(app, buffer, access));}
|
||||
|
|
|
@ -21,6 +21,9 @@ TYPEDEF int32_t bool32;
|
|||
/* DOC(int_color is an alias name to signal that an integer parameter or field is for a color value, colors are specified as 32 bit integers (8 bit + 24 bit) with 3 channels: 0x**RRGGBB.) */
|
||||
TYPEDEF uint32_t int_color;
|
||||
|
||||
/* DOC(Parse_Context_ID identifies a parse context, which is a guiding rule for the parser. Each buffer sets which parse context to use when it is parsed.) */
|
||||
TYPEDEF uint32_t Parse_Context_ID;
|
||||
|
||||
/* DOC(Buffer_ID is used to name a 4coder buffer. Each buffer has a unique id but when a buffer is closed it's id may be recycled by future, different buffers.) */
|
||||
TYPEDEF int32_t Buffer_ID;
|
||||
|
||||
|
@ -152,6 +155,9 @@ ENUM(int32_t, Buffer_Setting_ID){
|
|||
/* 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_ParserContext setting determines the parser context that guides the parser for the contents of this buffer. By default the value is 0, which represents the default C++ context.) */
|
||||
BufferSetting_ParserContext,
|
||||
|
||||
/* 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.) */
|
||||
BufferSetting_WrapLine,
|
||||
|
||||
|
@ -176,7 +182,7 @@ ENUM(int32_t, Buffer_Setting_ID){
|
|||
/* DOC(The BufferSetting_ReadOnly setting marks a buffer so that it can only be returned from buffer access calls that include an AccessProtected flag. By convention this means that edit commands that should not be applied to read only buffers will not edit this buffer.) */
|
||||
BufferSetting_ReadOnly,
|
||||
|
||||
/* DOC(The BufferSetting_VirtualWhitespace settings enables virtual whitespace on a buffer. Text buffers with virtual whitespace will set the indentation of every line to zero. Buffers with lexing enabled will use virtual white space to present the code with appealing indentation.) */
|
||||
/* DOC(The BufferSetting_VirtualWhitespace setting enables virtual whitespace on a buffer. Text buffers with virtual whitespace will set the indentation of every line to zero. Buffers with lexing enabled will use virtual white space to present the code with appealing indentation.) */
|
||||
BufferSetting_VirtualWhitespace,
|
||||
};
|
||||
|
||||
|
@ -389,8 +395,7 @@ STRUCT Mouse_State{
|
|||
|
||||
GLOBAL_VAR Mouse_State null_mouse_state = {0};
|
||||
|
||||
/* DOC(
|
||||
Range describes an integer range typically used for ranges within a buffer. Ranges tend are usually not passed as a Range struct into the API, but this struct is used to return ranges.
|
||||
/* DOC(Range describes an integer range typically used for ranges within a buffer. Ranges tend are usually not passed as a Range struct into the API, but this struct is used to return ranges.
|
||||
|
||||
Throughout the API ranges are thought of in the form [min,max) where max is "one past the end" of the range that is actually read/edited/modified.) */
|
||||
UNION Range{
|
||||
|
@ -408,6 +413,12 @@ UNION Range{
|
|||
};
|
||||
};
|
||||
|
||||
STRUCT Parser_String_And_Type{
|
||||
char *str;
|
||||
uint32_t length;
|
||||
uint32_t type;
|
||||
};
|
||||
|
||||
/*
|
||||
DOC(File_Info describes the name and type of a file.)
|
||||
DOC_SEE(File_List)
|
||||
|
|
|
@ -235,7 +235,8 @@ static char *default_extensions[] = {
|
|||
"hpp",
|
||||
"c",
|
||||
"h",
|
||||
"cc"
|
||||
"cc",
|
||||
"cs"
|
||||
};
|
||||
|
||||
struct Extension_List{
|
||||
|
@ -822,12 +823,11 @@ process_config_file(Application_Links *app){
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Framework Init Functions
|
||||
//
|
||||
|
||||
void
|
||||
static void
|
||||
init_memory(Application_Links *app){
|
||||
int32_t part_size = (32 << 20);
|
||||
int32_t general_size = (4 << 20);
|
||||
|
|
|
@ -13,6 +13,10 @@ TYPE: 'internal-for-default-system'
|
|||
#include "4coder_helper/4coder_bind_helper.h"
|
||||
#include "4coder_project_commands.cpp"
|
||||
|
||||
#include "languages/4coder_language_rust.h"
|
||||
#include "languages/4coder_language_cs.h"
|
||||
#include "languages/4coder_language_java.h"
|
||||
|
||||
HOOK_SIG(default_start){
|
||||
default_4coder_initialize(app);
|
||||
default_4coder_side_by_side_panels(app);
|
||||
|
@ -85,12 +89,36 @@ OPEN_FILE_HOOK_SIG(default_file_settings){
|
|||
int32_t extension_count = 0;
|
||||
char **extension_list = get_current_code_extensions(&extension_count);
|
||||
|
||||
Parse_Context_ID parse_context_id = 0;
|
||||
|
||||
if (buffer.file_name != 0 && buffer.size < (16 << 20)){
|
||||
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;
|
||||
|
||||
if (match(ext, "cs")){
|
||||
if (parse_context_language_cs == 0){
|
||||
init_language_cs(app);
|
||||
}
|
||||
parse_context_id = parse_context_language_cs;
|
||||
}
|
||||
|
||||
if (match(ext, "java")){
|
||||
if (parse_context_language_java == 0){
|
||||
init_language_java(app);
|
||||
}
|
||||
parse_context_id = parse_context_language_java;
|
||||
}
|
||||
|
||||
if (match(ext, "rs")){
|
||||
if (parse_context_language_rust == 0){
|
||||
init_language_rust(app);
|
||||
}
|
||||
parse_context_id = parse_context_language_rust;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -115,6 +143,7 @@ OPEN_FILE_HOOK_SIG(default_file_settings){
|
|||
buffer_set_setting(app, &buffer, BufferSetting_WrapPosition, default_wrap_width);
|
||||
buffer_set_setting(app, &buffer, BufferSetting_MinimumBaseWrapPosition, default_min_base_width);
|
||||
buffer_set_setting(app, &buffer, BufferSetting_MapID, map_id);
|
||||
buffer_set_setting(app, &buffer, BufferSetting_ParserContext, parse_context_id);
|
||||
|
||||
if (treat_as_todo){
|
||||
buffer_set_setting(app, &buffer, BufferSetting_WrapLine, true);
|
||||
|
|
|
@ -495,10 +495,10 @@ cpp_lex_nonalloc_null_end_no_limit(Cpp_Lex_Data *S_ptr, char *chunk, i32_4tech s
|
|||
S.pp_state -= LSPP_count;
|
||||
}
|
||||
|
||||
S.token.state_flags = S.pp_state;
|
||||
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;
|
||||
S.tb_pos = 0;
|
||||
|
@ -1093,41 +1093,44 @@ cpp_lex_nonalloc_null_end_no_limit(Cpp_Lex_Data *S_ptr, char *chunk, i32_4tech s
|
|||
if ((S.token.flags & CPP_TFLAG_PP_DIRECTIVE) == 0){
|
||||
switch (S.pp_state){
|
||||
case LSPP_macro_identifier:
|
||||
if (S.fsm.state != LS_identifier){
|
||||
S.token.type = CPP_TOKEN_JUNK;
|
||||
S.pp_state = LSPP_junk;
|
||||
}
|
||||
else{
|
||||
S.pp_state = LSPP_body;
|
||||
}
|
||||
break;
|
||||
{
|
||||
if (S.fsm.state != LS_identifier){
|
||||
S.token.type = CPP_TOKEN_JUNK;
|
||||
S.pp_state = LSPP_junk;
|
||||
}
|
||||
else{
|
||||
S.pp_state = LSPP_body;
|
||||
}
|
||||
}break;
|
||||
|
||||
case LSPP_identifier:
|
||||
if (S.fsm.state != LS_identifier){
|
||||
S.token.type = CPP_TOKEN_JUNK;
|
||||
}
|
||||
S.pp_state = LSPP_junk;
|
||||
break;
|
||||
{
|
||||
if (S.fsm.state != LS_identifier){
|
||||
S.token.type = CPP_TOKEN_JUNK;
|
||||
}
|
||||
S.pp_state = LSPP_junk;
|
||||
}break;
|
||||
|
||||
case LSPP_number:
|
||||
if (S.token.type != CPP_TOKEN_INTEGER_CONSTANT){
|
||||
S.token.type = CPP_TOKEN_JUNK;
|
||||
S.pp_state = LSPP_junk;
|
||||
}
|
||||
else{
|
||||
S.pp_state = LSPP_include;
|
||||
}
|
||||
break;
|
||||
{
|
||||
if (S.token.type != CPP_TOKEN_INTEGER_CONSTANT){
|
||||
S.token.type = CPP_TOKEN_JUNK;
|
||||
S.pp_state = LSPP_junk;
|
||||
}
|
||||
else{
|
||||
S.pp_state = LSPP_include;
|
||||
}
|
||||
}break;
|
||||
|
||||
case LSPP_junk:
|
||||
if (S.token.type != CPP_TOKEN_COMMENT){
|
||||
S.token.type = CPP_TOKEN_JUNK;
|
||||
}
|
||||
break;
|
||||
{
|
||||
if (S.token.type != CPP_TOKEN_COMMENT){
|
||||
S.token.type = CPP_TOKEN_JUNK;
|
||||
}
|
||||
}break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (S.fsm.emit_token){
|
||||
S.token.start = S.token_start;
|
||||
if (S.pos_overide){
|
||||
|
@ -1138,7 +1141,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 && S.pp_state){
|
||||
if (S.token.state_flags != LSPP_default && S.pp_state){
|
||||
S.token.flags |= CPP_TFLAG_PP_BODY;
|
||||
}
|
||||
}
|
||||
|
@ -1305,6 +1308,18 @@ DOC(Creates a new lex state in the form of a Cpp_Lex_Data struct and returns the
|
|||
return(data);
|
||||
}
|
||||
|
||||
API_EXPORT FCPP_LINK void
|
||||
cpp_rebase_tables(Cpp_Lex_Data *data, void *old_base, void *new_base){
|
||||
u8_4tech *old_base_ptr = (u8_4tech*)old_base;
|
||||
u8_4tech *new_base_ptr = (u8_4tech*)new_base;
|
||||
|
||||
u8_4tech *ptr = (u8_4tech*)data->keyword_table.keywords;
|
||||
data->keyword_table.keywords = (u64_4tech*)(ptr + (new_base_ptr - old_base_ptr));
|
||||
|
||||
ptr = (u8_4tech*)data->preprops_table.keywords;
|
||||
data->preprops_table.keywords = (u64_4tech*)(ptr + (new_base_ptr - old_base_ptr));
|
||||
}
|
||||
|
||||
FCPP_LINK char
|
||||
cpp_token_get_pp_state(u16_4tech bitfield){
|
||||
return (char)(bitfield);
|
||||
|
|
|
@ -425,7 +425,7 @@ DOC_PARAM(out, This parameter provides a buffer where the clipboard contents are
|
|||
DOC_PARAM(len, This parameter specifies the length of the out buffer.)
|
||||
DOC_RETURN(This call returns the size of the item associated with item_index.)
|
||||
|
||||
DOC(This function always returns the size of the item even if the output buffer is NULL. If the output buffer is too small to contain the whole string, it is filled with the first len character of the clipboard contents. The output string is not null terminated. )
|
||||
DOC(This function always returns the size of the item even if the output buffer is NULL. If the output buffer is too small to contain the whole string, it is filled with the first len character of the clipboard contents. The output string is not null terminated.)
|
||||
|
||||
DOC_SEE(The_4coder_Clipboard)
|
||||
*/{
|
||||
|
@ -445,6 +445,17 @@ DOC_SEE(The_4coder_Clipboard)
|
|||
return(size);
|
||||
}
|
||||
|
||||
API_EXPORT Parse_Context_ID
|
||||
Create_Parse_Context(Application_Links *app, Parser_String_And_Type *kw, uint32_t kw_count, Parser_String_And_Type *pp, uint32_t pp_count)
|
||||
{
|
||||
Command_Data *cmd = (Command_Data*)app->cmd_context;
|
||||
Models *models = cmd->models;
|
||||
|
||||
Parse_Context_ID id = parse_context_add(&models->parse_context_memory, &models->mem.general, kw, kw_count, pp, pp_count);
|
||||
|
||||
return(id);
|
||||
}
|
||||
|
||||
API_EXPORT int32_t
|
||||
Get_Buffer_Count(Application_Links *app)
|
||||
/*
|
||||
|
@ -854,6 +865,7 @@ DOC_RETURN(returns non-zero on success)
|
|||
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_ParserContext: *value_out = file->settings.parse_context_id; 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;
|
||||
|
@ -927,6 +939,27 @@ DOC_SEE(Buffer_Setting_ID)
|
|||
}
|
||||
}break;
|
||||
|
||||
case BufferSetting_ParserContext:
|
||||
{
|
||||
u32 fixed_value = parse_context_valid_id(&models->parse_context_memory, (u32)value);
|
||||
|
||||
if (file->settings.tokens_exist){
|
||||
if (fixed_value != file->settings.parse_context_id){
|
||||
file_kill_tokens(system, &models->mem.general, file);
|
||||
file->settings.parse_context_id = fixed_value;
|
||||
if (!file->settings.virtual_white){
|
||||
file_first_lex_parallel(system, models, file);
|
||||
}
|
||||
else{
|
||||
file_first_lex_serial(models, file);
|
||||
}
|
||||
}
|
||||
}
|
||||
else{
|
||||
file->settings.parse_context_id = fixed_value;
|
||||
}
|
||||
}break;
|
||||
|
||||
case BufferSetting_WrapLine:
|
||||
{
|
||||
file->settings.unwrapped_lines = !value;
|
||||
|
@ -940,7 +973,8 @@ DOC_SEE(Buffer_Setting_ID)
|
|||
}
|
||||
if (new_value != file->settings.display_width){
|
||||
Render_Font *font = system->font.get_render_data_by_id(file->settings.font_id);
|
||||
file_set_width(system, models, file, new_value, font);
|
||||
file->settings.display_width = new_value;
|
||||
file_measure_wraps_and_fix_cursor(system, models, file, font);
|
||||
}
|
||||
}break;
|
||||
|
||||
|
@ -952,7 +986,8 @@ DOC_SEE(Buffer_Setting_ID)
|
|||
}
|
||||
if (new_value != file->settings.minimum_base_display_width){
|
||||
Render_Font *font = system->font.get_render_data_by_id(file->settings.font_id);
|
||||
file_set_min_base_width(system, models, file, new_value, font);
|
||||
file->settings.minimum_base_display_width = new_value;
|
||||
file_measure_wraps_and_fix_cursor(system, models, file, font);
|
||||
}
|
||||
}break;
|
||||
|
||||
|
|
|
@ -93,7 +93,7 @@ struct Editing_File_Settings{
|
|||
i32 display_width;
|
||||
i32 minimum_base_display_width;
|
||||
i32 wrap_indicator;
|
||||
u32 parse_context_id;
|
||||
Parse_Context_ID parse_context_id;
|
||||
b32 dos_write_mode;
|
||||
b32 virtual_white;
|
||||
Font_ID font_id;
|
||||
|
|
|
@ -1979,18 +1979,6 @@ file_measure_wraps_and_fix_cursor(System_Functions *system, Models *models, Edit
|
|||
}
|
||||
}
|
||||
|
||||
internal void
|
||||
file_set_width(System_Functions *system, Models *models, Editing_File *file, i32 display_width, Render_Font *font){
|
||||
file->settings.display_width = display_width;
|
||||
file_measure_wraps_and_fix_cursor(system, models, file, font);
|
||||
}
|
||||
|
||||
internal void
|
||||
file_set_min_base_width(System_Functions *system, Models *models, Editing_File *file, i32 minimum_base_display_width, Render_Font *font){
|
||||
file->settings.minimum_base_display_width = minimum_base_display_width;
|
||||
file_measure_wraps_and_fix_cursor(system, models, file, font);
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
|
@ -2140,12 +2128,13 @@ Job_Callback_Sig(job_full_lex){
|
|||
i32 aligned_buffer_size = (text_size + 3)&(~3);
|
||||
|
||||
for (;memory->size < aligned_buffer_size + parse_context.memory_size;){
|
||||
void *old_base = memory->data;
|
||||
system->grow_thread_memory(memory);
|
||||
parse_context_rebase(&parse_context, old_base, memory->data);
|
||||
}
|
||||
|
||||
u8 *data_ptr = (u8*)memory->data;
|
||||
umem data_size = memory->size;
|
||||
|
||||
data_ptr += parse_context.memory_size;
|
||||
data_size -= parse_context.memory_size;
|
||||
|
||||
|
@ -2189,20 +2178,33 @@ Job_Callback_Sig(job_full_lex){
|
|||
if (system->check_cancel(thread)){
|
||||
return;
|
||||
}
|
||||
system->grow_thread_memory(memory);
|
||||
tokens.tokens = (Cpp_Token*)(memory->data);
|
||||
tokens.max_count = memory->size / sizeof(Cpp_Token);
|
||||
break;
|
||||
|
||||
case LexResult_HitTokenLimit:
|
||||
void *old_base = memory->data;
|
||||
system->grow_thread_memory(memory);
|
||||
cpp_rebase_tables(&lex, old_base, memory->data);
|
||||
|
||||
data_ptr = (u8*)memory->data;
|
||||
data_size = memory->size;
|
||||
data_ptr += parse_context.memory_size;
|
||||
data_size -= parse_context.memory_size;
|
||||
tokens.tokens = (Cpp_Token*)(data_ptr);
|
||||
tokens.max_count = (u32)(data_size / sizeof(Cpp_Token));
|
||||
}
|
||||
break;
|
||||
|
||||
case LexResult_HitTokenLimit:
|
||||
{
|
||||
if (system->check_cancel(thread)){
|
||||
return;
|
||||
}
|
||||
}break;
|
||||
|
||||
case LexResult_Finished: still_lexing = false; break;
|
||||
case LexResult_Finished:
|
||||
{
|
||||
still_lexing = false;
|
||||
}break;
|
||||
}
|
||||
} while (still_lexing);
|
||||
}while(still_lexing);
|
||||
|
||||
i32 new_max = l_round_up_i32(tokens.count+1, KB(1));
|
||||
|
||||
|
|
|
@ -9,12 +9,6 @@
|
|||
|
||||
// TOP
|
||||
|
||||
struct Parser_String_And_Type{
|
||||
char *str;
|
||||
u32 length;
|
||||
u32 type;
|
||||
};
|
||||
|
||||
struct Stored_Parse_Context{
|
||||
umem memsize;
|
||||
u64 *kw_keywords;
|
||||
|
@ -48,7 +42,16 @@ parse_context_init_memory(Parse_Context_Memory *parse_mem, void *mem, umem memsi
|
|||
parse_mem->parse_context_max = (u32)(memsize / sizeof(*parse_mem->parse_context_array));
|
||||
}
|
||||
|
||||
internal u32
|
||||
internal Parse_Context_ID
|
||||
parse_context_valid_id(Parse_Context_Memory *parse_mem, Parse_Context_ID id){
|
||||
Parse_Context_ID valid_id = 0;
|
||||
if (id > parse_mem->parse_context_max && id < parse_mem->parse_context_max*2){
|
||||
valid_id = id;
|
||||
}
|
||||
return(valid_id);
|
||||
}
|
||||
|
||||
internal Parse_Context_ID
|
||||
parse_context_add(Parse_Context_Memory *parse_mem, General_Memory *general, Parser_String_And_Type *kw_sats, u32 kw_count, Parser_String_And_Type *pp_sats, u32 pp_count){
|
||||
Stored_Parse_Context_Slot *slot = 0;
|
||||
if (parse_mem->free_sentinel.next != &parse_mem->free_sentinel){
|
||||
|
@ -138,7 +141,7 @@ struct Parse_Context{
|
|||
};
|
||||
|
||||
internal Parse_Context
|
||||
parse_context_get(Parse_Context_Memory *parse_mem, u32 id, void *mem, umem memsize){
|
||||
parse_context_get(Parse_Context_Memory *parse_mem, Parse_Context_ID id, void *mem, umem memsize){
|
||||
Parse_Context result = {0};
|
||||
|
||||
Stored_Parse_Context_Slot *slot = 0;
|
||||
|
@ -175,5 +178,17 @@ parse_context_get(Parse_Context_Memory *parse_mem, u32 id, void *mem, umem memsi
|
|||
return(result);
|
||||
}
|
||||
|
||||
internal void
|
||||
parse_context_rebase(Parse_Context *parse_mem, void *old_base, void *new_base){
|
||||
u8 *old_base_ptr = (u8*)old_base;
|
||||
u8 *new_base_ptr = (u8*)new_base;
|
||||
|
||||
u8 *ptr = (u8*)parse_mem->kw_table.keywords;
|
||||
parse_mem->kw_table.keywords = (u64*)(ptr + (new_base_ptr - old_base_ptr));
|
||||
|
||||
ptr = (u8*)parse_mem->pp_table.keywords;
|
||||
parse_mem->pp_table.keywords = (u64*)(ptr + (new_base_ptr - old_base_ptr));
|
||||
}
|
||||
|
||||
// BOTTOM
|
||||
|
||||
|
|
|
@ -0,0 +1,122 @@
|
|||
/*
|
||||
4coder_language_cs.h - Sets up the C# language context.
|
||||
|
||||
TYPE: 'langauge-description'
|
||||
*/
|
||||
|
||||
// TOP
|
||||
|
||||
#if !defined(FCODER_LANGUAGE_CS_H)
|
||||
#define FCODER_LANGUAGE_CS_H
|
||||
|
||||
static Parse_Context_ID parse_context_language_cs;
|
||||
|
||||
#define PSAT(s, t) {s, sizeof(s)-1, t}
|
||||
static void
|
||||
init_language_cs(Application_Links *app){
|
||||
if (parse_context_language_cs != 0) return;
|
||||
|
||||
Parser_String_And_Type kw[] = {
|
||||
PSAT("abstract", CPP_TOKEN_KEY_OTHER),
|
||||
PSAT("as", CPP_TOKEN_KEY_OTHER),
|
||||
PSAT("base", CPP_TOKEN_KEY_OTHER),
|
||||
PSAT("bool", CPP_TOKEN_KEY_OTHER),
|
||||
PSAT("byte", CPP_TOKEN_KEY_OTHER),
|
||||
PSAT("char", CPP_TOKEN_KEY_OTHER),
|
||||
PSAT("checked", CPP_TOKEN_KEY_OTHER),
|
||||
PSAT("class", CPP_TOKEN_KEY_OTHER),
|
||||
PSAT("const", CPP_TOKEN_KEY_OTHER),
|
||||
PSAT("decimal", CPP_TOKEN_KEY_OTHER),
|
||||
PSAT("delegate", CPP_TOKEN_KEY_OTHER),
|
||||
PSAT("double", CPP_TOKEN_KEY_OTHER),
|
||||
PSAT("enum", CPP_TOKEN_KEY_OTHER),
|
||||
PSAT("event", CPP_TOKEN_KEY_OTHER),
|
||||
PSAT("explicit", CPP_TOKEN_KEY_OTHER),
|
||||
PSAT("extern", CPP_TOKEN_KEY_OTHER),
|
||||
PSAT("false", CPP_TOKEN_KEY_OTHER),
|
||||
PSAT("fixed", CPP_TOKEN_KEY_OTHER),
|
||||
PSAT("float", CPP_TOKEN_KEY_OTHER),
|
||||
PSAT("implicit", CPP_TOKEN_KEY_OTHER),
|
||||
PSAT("int", CPP_TOKEN_KEY_OTHER),
|
||||
PSAT("interface", CPP_TOKEN_KEY_OTHER),
|
||||
PSAT("internal", CPP_TOKEN_KEY_OTHER),
|
||||
PSAT("is", CPP_TOKEN_KEY_OTHER),
|
||||
PSAT("long", CPP_TOKEN_KEY_OTHER),
|
||||
PSAT("namespace", CPP_TOKEN_KEY_OTHER),
|
||||
PSAT("new", CPP_TOKEN_KEY_OTHER),
|
||||
PSAT("null", CPP_TOKEN_KEY_OTHER),
|
||||
PSAT("object", CPP_TOKEN_KEY_OTHER),
|
||||
PSAT("operator", CPP_TOKEN_KEY_OTHER),
|
||||
PSAT("out", CPP_TOKEN_KEY_OTHER),
|
||||
PSAT("override", CPP_TOKEN_KEY_OTHER),
|
||||
PSAT("params", CPP_TOKEN_KEY_OTHER),
|
||||
PSAT("private", CPP_TOKEN_KEY_OTHER),
|
||||
PSAT("protected", CPP_TOKEN_KEY_OTHER),
|
||||
PSAT("public", CPP_TOKEN_KEY_OTHER),
|
||||
PSAT("readonly", CPP_TOKEN_KEY_OTHER),
|
||||
PSAT("ref", CPP_TOKEN_KEY_OTHER),
|
||||
PSAT("sbyte", CPP_TOKEN_KEY_OTHER),
|
||||
PSAT("sealed", CPP_TOKEN_KEY_OTHER),
|
||||
PSAT("short", CPP_TOKEN_KEY_OTHER),
|
||||
PSAT("sizeof", CPP_TOKEN_KEY_OTHER),
|
||||
PSAT("stackalloc", CPP_TOKEN_KEY_OTHER),
|
||||
PSAT("static", CPP_TOKEN_KEY_OTHER),
|
||||
PSAT("string", CPP_TOKEN_KEY_OTHER),
|
||||
PSAT("struct", CPP_TOKEN_KEY_OTHER),
|
||||
PSAT("this", CPP_TOKEN_KEY_OTHER),
|
||||
PSAT("true", CPP_TOKEN_KEY_OTHER),
|
||||
PSAT("typeof", CPP_TOKEN_KEY_OTHER),
|
||||
PSAT("uint", CPP_TOKEN_KEY_OTHER),
|
||||
PSAT("ulong", CPP_TOKEN_KEY_OTHER),
|
||||
PSAT("unchecked", CPP_TOKEN_KEY_OTHER),
|
||||
PSAT("unsafe", CPP_TOKEN_KEY_OTHER),
|
||||
PSAT("ushort", CPP_TOKEN_KEY_OTHER),
|
||||
PSAT("using", CPP_TOKEN_KEY_OTHER),
|
||||
PSAT("void", CPP_TOKEN_KEY_OTHER),
|
||||
PSAT("volatile", CPP_TOKEN_KEY_OTHER),
|
||||
|
||||
PSAT("if", CPP_TOKEN_KEY_CONTROL_FLOW),
|
||||
PSAT("else", CPP_TOKEN_KEY_CONTROL_FLOW),
|
||||
PSAT("switch", CPP_TOKEN_KEY_CONTROL_FLOW),
|
||||
PSAT("case", CPP_TOKEN_KEY_CONTROL_FLOW),
|
||||
PSAT("do", CPP_TOKEN_KEY_CONTROL_FLOW),
|
||||
PSAT("for", CPP_TOKEN_KEY_CONTROL_FLOW),
|
||||
PSAT("foreach", CPP_TOKEN_KEY_CONTROL_FLOW),
|
||||
PSAT("in", CPP_TOKEN_KEY_CONTROL_FLOW),
|
||||
PSAT("while", CPP_TOKEN_KEY_CONTROL_FLOW),
|
||||
PSAT("break", CPP_TOKEN_KEY_CONTROL_FLOW),
|
||||
PSAT("continue", CPP_TOKEN_KEY_CONTROL_FLOW),
|
||||
PSAT("default", CPP_TOKEN_KEY_CONTROL_FLOW),
|
||||
PSAT("goto", CPP_TOKEN_KEY_CONTROL_FLOW),
|
||||
PSAT("return", CPP_TOKEN_KEY_CONTROL_FLOW),
|
||||
PSAT("yield", CPP_TOKEN_KEY_CONTROL_FLOW),
|
||||
PSAT("throw", CPP_TOKEN_KEY_CONTROL_FLOW),
|
||||
PSAT("try", CPP_TOKEN_KEY_CONTROL_FLOW),
|
||||
PSAT("catch", CPP_TOKEN_KEY_CONTROL_FLOW),
|
||||
PSAT("finally", CPP_TOKEN_KEY_CONTROL_FLOW),
|
||||
PSAT("lock", CPP_TOKEN_KEY_CONTROL_FLOW),
|
||||
};
|
||||
|
||||
Parser_String_And_Type pp[] = {
|
||||
PSAT("if", CPP_PP_IF),
|
||||
PSAT("else", CPP_PP_ELSE),
|
||||
PSAT("elif", CPP_PP_ELIF),
|
||||
PSAT("endif", CPP_PP_ENDIF),
|
||||
PSAT("define", CPP_PP_DEFINED),
|
||||
PSAT("undef", CPP_PP_UNDEF),
|
||||
PSAT("warning", CPP_PP_ERROR),
|
||||
PSAT("error", CPP_PP_ERROR),
|
||||
PSAT("line", CPP_PP_LINE),
|
||||
PSAT("pragma", CPP_PP_PRAGMA),
|
||||
PSAT("region", CPP_PP_UNKNOWN),
|
||||
PSAT("endregion", CPP_PP_UNKNOWN),
|
||||
};
|
||||
|
||||
parse_context_language_cs = create_parse_context(app, kw, ArrayCount(kw), pp, ArrayCount(pp));
|
||||
}
|
||||
#undef PSAT
|
||||
|
||||
#endif
|
||||
|
||||
// BOTTOM
|
||||
|
|
@ -0,0 +1,82 @@
|
|||
/*
|
||||
4coder_language_java.h - Sets up the Java language context.
|
||||
|
||||
TYPE: 'langauge-description'
|
||||
*/
|
||||
|
||||
// TOP
|
||||
|
||||
#if !defined(FCODER_LANGUAGE_JAVA_H)
|
||||
#define FCODER_LANGUAGE_JAVA_H
|
||||
|
||||
static Parse_Context_ID parse_context_language_java;
|
||||
|
||||
#define PSAT(s, t) {s, sizeof(s)-1, t}
|
||||
static void
|
||||
init_language_java(Application_Links *app){
|
||||
if (parse_context_language_java != 0) return;
|
||||
|
||||
Parser_String_And_Type kw[] = {
|
||||
PSAT("abstract", CPP_TOKEN_KEY_OTHER),
|
||||
PSAT("assert", CPP_TOKEN_KEY_OTHER),
|
||||
PSAT("boolean", CPP_TOKEN_KEY_OTHER),
|
||||
PSAT("char", CPP_TOKEN_KEY_OTHER),
|
||||
PSAT("class", CPP_TOKEN_KEY_OTHER),
|
||||
PSAT("const", CPP_TOKEN_KEY_OTHER),
|
||||
PSAT("default", CPP_TOKEN_KEY_OTHER),
|
||||
PSAT("double", CPP_TOKEN_KEY_OTHER),
|
||||
PSAT("enum", CPP_TOKEN_KEY_OTHER),
|
||||
PSAT("extends", CPP_TOKEN_KEY_OTHER),
|
||||
PSAT("final", CPP_TOKEN_KEY_OTHER),
|
||||
PSAT("float", CPP_TOKEN_KEY_OTHER),
|
||||
PSAT("implements", CPP_TOKEN_KEY_OTHER),
|
||||
PSAT("import", CPP_TOKEN_KEY_OTHER),
|
||||
PSAT("instanceof", CPP_TOKEN_KEY_OTHER),
|
||||
PSAT("int", CPP_TOKEN_KEY_OTHER),
|
||||
PSAT("interface", CPP_TOKEN_KEY_OTHER),
|
||||
PSAT("long", CPP_TOKEN_KEY_OTHER),
|
||||
PSAT("native", CPP_TOKEN_KEY_OTHER),
|
||||
PSAT("new", CPP_TOKEN_KEY_OTHER),
|
||||
PSAT("package", CPP_TOKEN_KEY_OTHER),
|
||||
PSAT("private", CPP_TOKEN_KEY_OTHER),
|
||||
PSAT("protected", CPP_TOKEN_KEY_OTHER),
|
||||
PSAT("public", CPP_TOKEN_KEY_OTHER),
|
||||
PSAT("return", CPP_TOKEN_KEY_OTHER),
|
||||
PSAT("short", CPP_TOKEN_KEY_OTHER),
|
||||
PSAT("static", CPP_TOKEN_KEY_OTHER),
|
||||
PSAT("strictfp", CPP_TOKEN_KEY_OTHER),
|
||||
PSAT("super", CPP_TOKEN_KEY_OTHER),
|
||||
PSAT("synchronized", CPP_TOKEN_KEY_OTHER),
|
||||
PSAT("this", CPP_TOKEN_KEY_OTHER),
|
||||
PSAT("transient", CPP_TOKEN_KEY_OTHER),
|
||||
PSAT("void", CPP_TOKEN_KEY_OTHER),
|
||||
PSAT("volatile", CPP_TOKEN_KEY_OTHER),
|
||||
PSAT("true", CPP_TOKEN_KEY_OTHER),
|
||||
PSAT("false", CPP_TOKEN_KEY_OTHER),
|
||||
PSAT("null", CPP_TOKEN_KEY_OTHER),
|
||||
|
||||
PSAT("if", CPP_TOKEN_KEY_CONTROL_FLOW),
|
||||
PSAT("else", CPP_TOKEN_KEY_CONTROL_FLOW),
|
||||
PSAT("switch", CPP_TOKEN_KEY_CONTROL_FLOW),
|
||||
PSAT("case", CPP_TOKEN_KEY_CONTROL_FLOW),
|
||||
PSAT("while", CPP_TOKEN_KEY_CONTROL_FLOW),
|
||||
PSAT("do", CPP_TOKEN_KEY_CONTROL_FLOW),
|
||||
PSAT("for", CPP_TOKEN_KEY_CONTROL_FLOW),
|
||||
PSAT("goto", CPP_TOKEN_KEY_CONTROL_FLOW),
|
||||
PSAT("break", CPP_TOKEN_KEY_CONTROL_FLOW),
|
||||
PSAT("continue", CPP_TOKEN_KEY_CONTROL_FLOW),
|
||||
PSAT("throw", CPP_TOKEN_KEY_CONTROL_FLOW),
|
||||
PSAT("throws", CPP_TOKEN_KEY_CONTROL_FLOW),
|
||||
PSAT("try", CPP_TOKEN_KEY_CONTROL_FLOW),
|
||||
PSAT("catch", CPP_TOKEN_KEY_CONTROL_FLOW),
|
||||
PSAT("finally", CPP_TOKEN_KEY_CONTROL_FLOW),
|
||||
};
|
||||
|
||||
parse_context_language_java = create_parse_context(app, kw, ArrayCount(kw), 0, 0);
|
||||
}
|
||||
#undef PSAT
|
||||
|
||||
#endif
|
||||
|
||||
// BOTTOM
|
||||
|
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
4coder_language_rust.h - Sets up the Rust language context.
|
||||
|
||||
TYPE: 'langauge-description'
|
||||
*/
|
||||
|
||||
// TOP
|
||||
|
||||
#if !defined(FCODER_LANGUAGE_RUST_H)
|
||||
#define FCODER_LANGUAGE_RUST_H
|
||||
|
||||
static Parse_Context_ID parse_context_language_rust;
|
||||
|
||||
#define PSAT(s, t) {s, sizeof(s)-1, t}
|
||||
static void
|
||||
init_language_rust(Application_Links *app){
|
||||
if (parse_context_language_rust != 0) return;
|
||||
|
||||
Parser_String_And_Type kw[] = {
|
||||
PSAT("abstract", CPP_TOKEN_KEY_OTHER),
|
||||
PSAT("alignof", CPP_TOKEN_KEY_OTHER),
|
||||
PSAT("as", CPP_TOKEN_KEY_OTHER),
|
||||
PSAT("become", CPP_TOKEN_KEY_OTHER),
|
||||
PSAT("box", CPP_TOKEN_KEY_OTHER),
|
||||
PSAT("const", CPP_TOKEN_KEY_OTHER),
|
||||
PSAT("crate", CPP_TOKEN_KEY_OTHER),
|
||||
PSAT("enum", CPP_TOKEN_KEY_OTHER),
|
||||
PSAT("extern", CPP_TOKEN_KEY_OTHER),
|
||||
PSAT("false", CPP_TOKEN_KEY_OTHER),
|
||||
PSAT("final", CPP_TOKEN_KEY_OTHER),
|
||||
PSAT("fn", CPP_TOKEN_KEY_OTHER),
|
||||
PSAT("impl", CPP_TOKEN_KEY_OTHER),
|
||||
PSAT("in", CPP_TOKEN_KEY_OTHER),
|
||||
PSAT("let", CPP_TOKEN_KEY_OTHER),
|
||||
PSAT("loop", CPP_TOKEN_KEY_OTHER),
|
||||
PSAT("macro", CPP_TOKEN_KEY_OTHER),
|
||||
PSAT("match", CPP_TOKEN_KEY_OTHER),
|
||||
PSAT("mod", CPP_TOKEN_KEY_OTHER),
|
||||
PSAT("move", CPP_TOKEN_KEY_OTHER),
|
||||
PSAT("mut", CPP_TOKEN_KEY_OTHER),
|
||||
PSAT("offsetof", CPP_TOKEN_KEY_OTHER),
|
||||
PSAT("override", CPP_TOKEN_KEY_OTHER),
|
||||
PSAT("priv", CPP_TOKEN_KEY_OTHER),
|
||||
PSAT("proc", CPP_TOKEN_KEY_OTHER),
|
||||
PSAT("pub", CPP_TOKEN_KEY_OTHER),
|
||||
PSAT("pure", CPP_TOKEN_KEY_OTHER),
|
||||
PSAT("ref", CPP_TOKEN_KEY_OTHER),
|
||||
PSAT("return", CPP_TOKEN_KEY_OTHER),
|
||||
PSAT("Self", CPP_TOKEN_KEY_OTHER),
|
||||
PSAT("self", CPP_TOKEN_KEY_OTHER),
|
||||
PSAT("sizeof", CPP_TOKEN_KEY_OTHER),
|
||||
PSAT("static", CPP_TOKEN_KEY_OTHER),
|
||||
PSAT("struct", CPP_TOKEN_KEY_OTHER),
|
||||
PSAT("super", CPP_TOKEN_KEY_OTHER),
|
||||
PSAT("trait", CPP_TOKEN_KEY_OTHER),
|
||||
PSAT("true", CPP_TOKEN_KEY_OTHER),
|
||||
PSAT("type", CPP_TOKEN_KEY_OTHER),
|
||||
PSAT("typeof", CPP_TOKEN_KEY_OTHER),
|
||||
PSAT("unsafe", CPP_TOKEN_KEY_OTHER),
|
||||
PSAT("unsized", CPP_TOKEN_KEY_OTHER),
|
||||
PSAT("use", CPP_TOKEN_KEY_OTHER),
|
||||
PSAT("virtual", CPP_TOKEN_KEY_OTHER),
|
||||
PSAT("where", CPP_TOKEN_KEY_OTHER),
|
||||
|
||||
PSAT("break", CPP_TOKEN_KEY_CONTROL_FLOW),
|
||||
PSAT("continue", CPP_TOKEN_KEY_CONTROL_FLOW),
|
||||
PSAT("do", CPP_TOKEN_KEY_CONTROL_FLOW),
|
||||
PSAT("else", CPP_TOKEN_KEY_CONTROL_FLOW),
|
||||
PSAT("for", CPP_TOKEN_KEY_CONTROL_FLOW),
|
||||
PSAT("if", CPP_TOKEN_KEY_CONTROL_FLOW),
|
||||
PSAT("while", CPP_TOKEN_KEY_CONTROL_FLOW),
|
||||
PSAT("yield", CPP_TOKEN_KEY_CONTROL_FLOW),
|
||||
};
|
||||
|
||||
parse_context_language_rust = create_parse_context(app, kw, ArrayCount(kw), 0, 0);
|
||||
}
|
||||
#undef PSAT
|
||||
|
||||
#endif
|
||||
|
||||
// BOTTOM
|
|
@ -485,8 +485,8 @@ static void
|
|||
standard_build(char *cdir, u32 flags){
|
||||
fsm_generator(cdir);
|
||||
metagen(cdir);
|
||||
do_buildsuper(cdir, Custom_Experiments, flags);
|
||||
//do_buildsuper(cdir, Custom_Casey, flags);
|
||||
//do_buildsuper(cdir, Custom_Experiments, flags);
|
||||
do_buildsuper(cdir, Custom_Casey, flags);
|
||||
//do_buildsuper(cdir, Custom_ChronalVim, flags);
|
||||
build_main(cdir, flags);
|
||||
}
|
||||
|
|
|
@ -1101,7 +1101,7 @@ CUSTOM_COMMAND_SIG(casey_execute_arbitrary_command)
|
|||
}
|
||||
else if(match(bar.string, make_lit_string("open menu")))
|
||||
{
|
||||
exec_command(app, cmdid_open_menu);
|
||||
// exec_command(app, cmdid_open_menu);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue