Organize config parsing stuff

This commit is contained in:
Allen Webster 2020-11-24 16:26:11 -08:00
parent 9241285f74
commit 7464320e56
5 changed files with 198 additions and 168 deletions

View File

@ -4,6 +4,9 @@
// TOP // TOP
////////////////////////////////
// NOTE(allen): Extension List
function String_Const_u8_Array function String_Const_u8_Array
parse_extension_line_to_extension_list(Application_Links *app, parse_extension_line_to_extension_list(Application_Links *app,
Arena *arena, String_Const_u8 str){ Arena *arena, String_Const_u8 str){
@ -33,6 +36,7 @@ parse_extension_line_to_extension_list(Application_Links *app,
} }
//////////////////////////////// ////////////////////////////////
// NOTE(allen): Built in Mapping
function void function void
setup_built_in_mapping(Application_Links *app, String_Const_u8 name, Mapping *mapping, i64 global_id, i64 file_id, i64 code_id){ setup_built_in_mapping(Application_Links *app, String_Const_u8 name, Mapping *mapping, i64 global_id, i64 file_id, i64 code_id){
@ -59,6 +63,7 @@ setup_built_in_mapping(Application_Links *app, String_Const_u8 name, Mapping *ma
} }
//////////////////////////////// ////////////////////////////////
// NOTE(allen): Errors
function Error_Location function Error_Location
get_error_location(Application_Links *app, u8 *base, u8 *pos){ get_error_location(Application_Links *app, u8 *base, u8 *pos){
@ -99,35 +104,40 @@ config_stringize_errors(Application_Links *app, Arena *arena, Config *parsed){
} }
//////////////////////////////// ////////////////////////////////
// NOTE(allen): Parser
function Config_Parser
def_config_parser_init(Arena *arena, String_Const_u8 file_name, String_Const_u8 data, Token_Array array){
Config_Parser ctx = {};
ctx.token = array.tokens - 1;
ctx.opl = array.tokens + array.count;
ctx.file_name = file_name;
ctx.data = data;
ctx.arena = arena;
def_config_parser_inc(&ctx);
return(ctx);
}
function void function void
config_parser__advance_to_next(Config_Parser *ctx){ def_config_parser_inc(Config_Parser *ctx){
Token *t = ctx->token; Token *t = ctx->token;
Token *e = ctx->end; Token *opl = ctx->opl;
for (t += 1; for (t += 1;
t < e && (t->kind == TokenBaseKind_Comment || t < opl && (t->kind == TokenBaseKind_Comment ||
t->kind == TokenBaseKind_Whitespace); t->kind == TokenBaseKind_Whitespace);
t += 1); t += 1);
ctx->token = t; ctx->token = t;
} }
function Config_Parser function u8*
make_config_parser(Arena *arena, String_Const_u8 file_name, String_Const_u8 data, Token_Array array){ def_config_parser_get_pos(Config_Parser *ctx){
Config_Parser ctx = {}; return(ctx->data.str + ctx->token->pos);
ctx.start = array.tokens;
ctx.token = ctx.start - 1;
ctx.end = ctx.start + array.count;
ctx.file_name = file_name;
ctx.data = data;
ctx.arena = arena;
config_parser__advance_to_next(&ctx);
return(ctx);
} }
function b32 function b32
config_parser__recognize_base_token(Config_Parser *ctx, Token_Base_Kind kind){ def_config_parser_recognize_base_kind(Config_Parser *ctx, Token_Base_Kind kind){
b32 result = false; b32 result = false;
if (ctx->start <= ctx->token && ctx->token < ctx->end){ if (ctx->token < ctx->opl){
result = (ctx->token->kind == kind); result = (ctx->token->kind == kind);
} }
else if (kind == TokenBaseKind_EOF){ else if (kind == TokenBaseKind_EOF){
@ -137,9 +147,9 @@ config_parser__recognize_base_token(Config_Parser *ctx, Token_Base_Kind kind){
} }
function b32 function b32
config_parser__recognize_token(Config_Parser *ctx, Token_Cpp_Kind kind){ def_config_parser_recognize_cpp_kind(Config_Parser *ctx, Token_Cpp_Kind kind){
b32 result = false; b32 result = false;
if (ctx->start <= ctx->token && ctx->token < ctx->end){ if (ctx->token < ctx->opl){
result = (ctx->token->sub_kind == kind); result = (ctx->token->sub_kind == kind);
} }
else if (kind == TokenCppKind_EOF){ else if (kind == TokenCppKind_EOF){
@ -149,30 +159,54 @@ config_parser__recognize_token(Config_Parser *ctx, Token_Cpp_Kind kind){
} }
function b32 function b32
config_parser__recognize_boolean(Config_Parser *ctx){ def_config_parser_recognize_boolean(Config_Parser *ctx){
b32 result = false; b32 result = false;
Token *token = ctx->token; Token *token = ctx->token;
if (ctx->start <= ctx->token && ctx->token < ctx->end){ if (ctx->token < ctx->opl){
result = (token->sub_kind == TokenCppKind_LiteralTrue || result = (token->sub_kind == TokenCppKind_LiteralTrue ||
token->sub_kind == TokenCppKind_LiteralFalse); token->sub_kind == TokenCppKind_LiteralFalse);
} }
return(result); return(result);
} }
function b32
def_config_parser_recognize_text(Config_Parser *ctx, String_Const_u8 text){
String_Const_u8 lexeme = def_config_parser_get_lexeme(ctx);
return(lexeme.str != 0 && string_match(lexeme, text));
}
function b32
def_config_parser_match_cpp_kind(Config_Parser *ctx, Token_Cpp_Kind kind){
b32 result = def_config_parser_recognize_cpp_kind(ctx, kind);
if (result){
def_config_parser_inc(ctx);
}
return(result);
}
function b32
def_config_parser_match_text(Config_Parser *ctx, String_Const_u8 text){
b32 result = def_config_parser_recognize_text(ctx, text);
if (result){
def_config_parser_inc(ctx);
}
return(result);
}
function String_Const_u8 function String_Const_u8
config_parser__get_lexeme(Config_Parser *ctx){ def_config_parser_get_lexeme(Config_Parser *ctx){
String_Const_u8 lexeme = {}; String_Const_u8 lexeme = {};
Token *token = ctx->token; Token *token = ctx->token;
if (ctx->start <= token && token < ctx->end){ if (token < ctx->opl){
lexeme = SCu8(ctx->data.str + token->pos, token->size); lexeme = SCu8(ctx->data.str + token->pos, token->size);
} }
return(lexeme); return(lexeme);
} }
function Config_Integer function Config_Integer
config_parser__get_int(Config_Parser *ctx){ def_config_parser_get_int(Config_Parser *ctx){
Config_Integer config_integer = {}; Config_Integer config_integer = {};
String_Const_u8 str = config_parser__get_lexeme(ctx); String_Const_u8 str = def_config_parser_get_lexeme(ctx);
if (string_match(string_prefix(str, 2), string_u8_litexpr("0x"))){ if (string_match(string_prefix(str, 2), string_u8_litexpr("0x"))){
config_integer.is_signed = false; config_integer.is_signed = false;
config_integer.uinteger = (u32)(string_to_integer(string_skip(str, 2), 16)); config_integer.uinteger = (u32)(string_to_integer(string_skip(str, 2), 16));
@ -192,62 +226,26 @@ config_parser__get_int(Config_Parser *ctx){
} }
function b32 function b32
config_parser__get_boolean(Config_Parser *ctx){ def_config_parser_get_boolean(Config_Parser *ctx){
String_Const_u8 str = config_parser__get_lexeme(ctx); String_Const_u8 str = def_config_parser_get_lexeme(ctx);
return(string_match(str, string_u8_litexpr("true"))); return(string_match(str, string_u8_litexpr("true")));
} }
function b32
config_parser__recognize_text(Config_Parser *ctx, String_Const_u8 text){
String_Const_u8 lexeme = config_parser__get_lexeme(ctx);
return(lexeme.str != 0 && string_match(lexeme, text));
}
function b32
config_parser__match_token(Config_Parser *ctx, Token_Cpp_Kind kind){
b32 result = config_parser__recognize_token(ctx, kind);
if (result){
config_parser__advance_to_next(ctx);
}
return(result);
}
function b32
config_parser__match_text(Config_Parser *ctx, String_Const_u8 text){
b32 result = config_parser__recognize_text(ctx, text);
if (result){
config_parser__advance_to_next(ctx);
}
return(result);
}
#define config_parser__match_text_lit(c,s) config_parser__match_text((c), string_u8_litexpr(s))
function Config *config_parser__config (Config_Parser *ctx);
function i32 *config_parser__version (Config_Parser *ctx);
function Config_Assignment *config_parser__assignment(Config_Parser *ctx);
function Config_LValue *config_parser__lvalue (Config_Parser *ctx);
function Config_RValue *config_parser__rvalue (Config_Parser *ctx);
function Config_Compound *config_parser__compound (Config_Parser *ctx);
function Config_Compound_Element *config_parser__element (Config_Parser *ctx);
function Config* function Config*
config_parse(Application_Links *app, Arena *arena, String_Const_u8 file_name, def_config_parse(Application_Links *app, Arena *arena, String_Const_u8 file_name,
String_Const_u8 data, Token_Array array){ String_Const_u8 data, Token_Array array){
ProfileScope(app, "config parse"); ProfileScope(app, "config parse");
Temp_Memory restore_point = begin_temp(arena); Temp_Memory restore_point = begin_temp(arena);
Config_Parser ctx = make_config_parser(arena, file_name, data, array); Config_Parser ctx = def_config_parser_init(arena, file_name, data, array);
Config *config = config_parser__config(&ctx); Config *config = def_config_parser_config(&ctx);
if (config == 0){ if (config == 0){
end_temp(restore_point); end_temp(restore_point);
} }
return(config); return(config);
} }
// TODO(allen): Move to string library
function Config_Error* function Config_Error*
config_error_push(Arena *arena, Config_Error_List *list, String_Const_u8 file_name, def_config_push_error(Arena *arena, Config_Error_List *list, String_Const_u8 file_name, u8 *pos, char *error_text){
u8 *pos, char *error_text){
Config_Error *error = push_array(arena, Config_Error, 1); Config_Error *error = push_array(arena, Config_Error, 1);
zdll_push_back(list->first, list->last, error); zdll_push_back(list->first, list->last, error);
list->count += 1; list->count += 1;
@ -257,30 +255,25 @@ config_error_push(Arena *arena, Config_Error_List *list, String_Const_u8 file_na
return(error); return(error);
} }
function u8* function void
config_parser__get_pos(Config_Parser *ctx){ def_config_parser_push_error(Config_Parser *ctx, u8 *pos, char *error_text){
return(ctx->data.str + ctx->token->pos); def_config_push_error(ctx->arena, &ctx->errors, ctx->file_name, pos, error_text);
} }
function void function void
config_parser__log_error_pos(Config_Parser *ctx, u8 *pos, char *error_text){ def_config_parser_push_error_here(Config_Parser *ctx, char *error_text){
config_error_push(ctx->arena, &ctx->errors, ctx->file_name, pos, error_text); def_config_parser_push_error(ctx, def_config_parser_get_pos(ctx), error_text);
}
function void
config_parser__log_error(Config_Parser *ctx, char *error_text){
config_parser__log_error_pos(ctx, config_parser__get_pos(ctx), error_text);
} }
function Config* function Config*
config_parser__config(Config_Parser *ctx){ def_config_parser_config(Config_Parser *ctx){
i32 *version = config_parser__version(ctx); i32 *version = def_config_parser_version(ctx);
Config_Assignment *first = 0; Config_Assignment *first = 0;
Config_Assignment *last = 0; Config_Assignment *last = 0;
i32 count = 0; i32 count = 0;
for (;!config_parser__recognize_token(ctx, TokenCppKind_EOF);){ for (;!def_config_parser_recognize_cpp_kind(ctx, TokenCppKind_EOF);){
Config_Assignment *assignment = config_parser__assignment(ctx); Config_Assignment *assignment = def_config_parser_assignment(ctx);
if (assignment != 0){ if (assignment != 0){
zdll_push_back(first, last, assignment); zdll_push_back(first, last, assignment);
count += 1; count += 1;
@ -302,43 +295,43 @@ config_parser__config(Config_Parser *ctx){
function void function void
config_parser__recover_parse(Config_Parser *ctx){ config_parser__recover_parse(Config_Parser *ctx){
for (;;){ for (;;){
if (config_parser__match_token(ctx, TokenCppKind_Semicolon)){ if (def_config_parser_match_cpp_kind(ctx, TokenCppKind_Semicolon)){
break; break;
} }
if (config_parser__recognize_token(ctx, TokenCppKind_EOF)){ if (def_config_parser_recognize_cpp_kind(ctx, TokenCppKind_EOF)){
break; break;
} }
config_parser__advance_to_next(ctx); def_config_parser_inc(ctx);
} }
} }
function i32* function i32*
config_parser__version(Config_Parser *ctx){ def_config_parser_version(Config_Parser *ctx){
require(config_parser__match_text_lit(ctx, "version")); require(def_config_parser_match_text(ctx, string_u8_litinit("version")));
if (!config_parser__match_token(ctx, TokenCppKind_ParenOp)){ if (!def_config_parser_match_cpp_kind(ctx, TokenCppKind_ParenOp)){
config_parser__log_error(ctx, "expected token '(' for version specifier: 'version(#)'"); def_config_parser_push_error_here(ctx, "expected token '(' for version specifier: 'version(#)'");
config_parser__recover_parse(ctx); config_parser__recover_parse(ctx);
return(0); return(0);
} }
if (!config_parser__recognize_base_token(ctx, TokenBaseKind_LiteralInteger)){ if (!def_config_parser_recognize_base_kind(ctx, TokenBaseKind_LiteralInteger)){
config_parser__log_error(ctx, "expected an integer constant for version specifier: 'version(#)'"); def_config_parser_push_error_here(ctx, "expected an integer constant for version specifier: 'version(#)'");
config_parser__recover_parse(ctx); config_parser__recover_parse(ctx);
return(0); return(0);
} }
Config_Integer value = config_parser__get_int(ctx); Config_Integer value = def_config_parser_get_int(ctx);
config_parser__advance_to_next(ctx); def_config_parser_inc(ctx);
if (!config_parser__match_token(ctx, TokenCppKind_ParenCl)){ if (!def_config_parser_match_cpp_kind(ctx, TokenCppKind_ParenCl)){
config_parser__log_error(ctx, "expected token ')' for version specifier: 'version(#)'"); def_config_parser_push_error_here(ctx, "expected token ')' for version specifier: 'version(#)'");
config_parser__recover_parse(ctx); config_parser__recover_parse(ctx);
return(0); return(0);
} }
if (!config_parser__match_token(ctx, TokenCppKind_Semicolon)){ if (!def_config_parser_match_cpp_kind(ctx, TokenCppKind_Semicolon)){
config_parser__log_error(ctx, "expected token ';' for version specifier: 'version(#)'"); def_config_parser_push_error_here(ctx, "expected token ';' for version specifier: 'version(#)'");
config_parser__recover_parse(ctx); config_parser__recover_parse(ctx);
return(0); return(0);
} }
@ -349,36 +342,36 @@ config_parser__version(Config_Parser *ctx){
} }
function Config_Assignment* function Config_Assignment*
config_parser__assignment(Config_Parser *ctx){ def_config_parser_assignment(Config_Parser *ctx){
u8 *pos = config_parser__get_pos(ctx); u8 *pos = def_config_parser_get_pos(ctx);
Config_LValue *l = config_parser__lvalue(ctx); Config_LValue *l = def_config_parser_lvalue(ctx);
if (l == 0){ if (l == 0){
config_parser__log_error(ctx, "expected an l-value; l-value formats: 'identifier', 'identifier[#]'"); def_config_parser_push_error_here(ctx, "expected an l-value; l-value formats: 'identifier', 'identifier[#]'");
config_parser__recover_parse(ctx); config_parser__recover_parse(ctx);
return(0); return(0);
} }
if (!config_parser__match_token(ctx, TokenCppKind_Eq)){ if (!def_config_parser_match_cpp_kind(ctx, TokenCppKind_Eq)){
config_parser__log_error(ctx, "expected token '=' for assignment: 'l-value = r-value;'"); def_config_parser_push_error_here(ctx, "expected token '=' for assignment: 'l-value = r-value;'");
config_parser__recover_parse(ctx); config_parser__recover_parse(ctx);
return(0); return(0);
} }
Config_RValue *r = config_parser__rvalue(ctx); Config_RValue *r = def_config_parser_rvalue(ctx);
if (r == 0){ if (r == 0){
config_parser__log_error(ctx, "expected an r-value; r-value formats:\n" def_config_parser_push_error_here(ctx, "expected an r-value; r-value formats:\n"
"\tconstants (true, false, integers, hexadecimal integers, strings, characters)\n" "\tconstants (true, false, integers, hexadecimal integers, strings, characters)\n"
"\tany l-value that is set in the file\n" "\tany l-value that is set in the file\n"
"\tcompound: '{ compound-element, compound-element, compound-element ...}'\n" "\tcompound: '{ compound-element, compound-element, compound-element ...}'\n"
"\ta compound-element is an r-value, and can have a layout specifier\n" "\ta compound-element is an r-value, and can have a layout specifier\n"
"\tcompound-element with layout specifier: .name = r-value, .integer = r-value"); "\tcompound-element with layout specifier: .name = r-value, .integer = r-value");
config_parser__recover_parse(ctx); config_parser__recover_parse(ctx);
return(0); return(0);
} }
if (!config_parser__match_token(ctx, TokenCppKind_Semicolon)){ if (!def_config_parser_match_cpp_kind(ctx, TokenCppKind_Semicolon)){
config_parser__log_error(ctx, "expected token ';' for assignment: 'l-value = r-value;'"); def_config_parser_push_error_here(ctx, "expected token ';' for assignment: 'l-value = r-value;'");
config_parser__recover_parse(ctx); config_parser__recover_parse(ctx);
return(0); return(0);
} }
@ -391,18 +384,18 @@ config_parser__assignment(Config_Parser *ctx){
} }
function Config_LValue* function Config_LValue*
config_parser__lvalue(Config_Parser *ctx){ def_config_parser_lvalue(Config_Parser *ctx){
require(config_parser__recognize_token(ctx, TokenCppKind_Identifier)); require(def_config_parser_recognize_cpp_kind(ctx, TokenCppKind_Identifier));
String_Const_u8 identifier = config_parser__get_lexeme(ctx); String_Const_u8 identifier = def_config_parser_get_lexeme(ctx);
config_parser__advance_to_next(ctx); def_config_parser_inc(ctx);
i32 index = 0; i32 index = 0;
if (config_parser__match_token(ctx, TokenCppKind_BrackOp)){ if (def_config_parser_match_cpp_kind(ctx, TokenCppKind_BrackOp)){
require(config_parser__recognize_base_token(ctx, TokenBaseKind_LiteralInteger)); require(def_config_parser_recognize_base_kind(ctx, TokenBaseKind_LiteralInteger));
Config_Integer value = config_parser__get_int(ctx); Config_Integer value = def_config_parser_get_int(ctx);
index = value.integer; index = value.integer;
config_parser__advance_to_next(ctx); def_config_parser_inc(ctx);
require(config_parser__match_token(ctx, TokenCppKind_BrackCl)); require(def_config_parser_match_cpp_kind(ctx, TokenCppKind_BrackCl));
} }
Config_LValue *lvalue = push_array_zero(ctx->arena, Config_LValue, 1); Config_LValue *lvalue = push_array_zero(ctx->arena, Config_LValue, 1);
@ -412,33 +405,33 @@ config_parser__lvalue(Config_Parser *ctx){
} }
function Config_RValue* function Config_RValue*
config_parser__rvalue(Config_Parser *ctx){ def_config_parser_rvalue(Config_Parser *ctx){
Config_RValue *rvalue = 0; Config_RValue *rvalue = 0;
if (config_parser__recognize_token(ctx, TokenCppKind_Identifier)){ if (def_config_parser_recognize_cpp_kind(ctx, TokenCppKind_Identifier)){
Config_LValue *l = config_parser__lvalue(ctx); Config_LValue *l = def_config_parser_lvalue(ctx);
require(l != 0); require(l != 0);
rvalue = push_array_zero(ctx->arena, Config_RValue, 1); rvalue = push_array_zero(ctx->arena, Config_RValue, 1);
rvalue->type = ConfigRValueType_LValue; rvalue->type = ConfigRValueType_LValue;
rvalue->lvalue = l; rvalue->lvalue = l;
} }
else if (config_parser__recognize_token(ctx, TokenCppKind_BraceOp)){ else if (def_config_parser_recognize_cpp_kind(ctx, TokenCppKind_BraceOp)){
config_parser__advance_to_next(ctx); def_config_parser_inc(ctx);
Config_Compound *compound = config_parser__compound(ctx); Config_Compound *compound = def_config_parser_compound(ctx);
require(compound != 0); require(compound != 0);
rvalue = push_array_zero(ctx->arena, Config_RValue, 1); rvalue = push_array_zero(ctx->arena, Config_RValue, 1);
rvalue->type = ConfigRValueType_Compound; rvalue->type = ConfigRValueType_Compound;
rvalue->compound = compound; rvalue->compound = compound;
} }
else if (config_parser__recognize_boolean(ctx)){ else if (def_config_parser_recognize_boolean(ctx)){
b32 b = config_parser__get_boolean(ctx); b32 b = def_config_parser_get_boolean(ctx);
config_parser__advance_to_next(ctx); def_config_parser_inc(ctx);
rvalue = push_array_zero(ctx->arena, Config_RValue, 1); rvalue = push_array_zero(ctx->arena, Config_RValue, 1);
rvalue->type = ConfigRValueType_Boolean; rvalue->type = ConfigRValueType_Boolean;
rvalue->boolean = b; rvalue->boolean = b;
} }
else if (config_parser__recognize_base_token(ctx, TokenBaseKind_LiteralInteger)){ else if (def_config_parser_recognize_base_kind(ctx, TokenBaseKind_LiteralInteger)){
Config_Integer value = config_parser__get_int(ctx); Config_Integer value = def_config_parser_get_int(ctx);
config_parser__advance_to_next(ctx); def_config_parser_inc(ctx);
rvalue = push_array_zero(ctx->arena, Config_RValue, 1); rvalue = push_array_zero(ctx->arena, Config_RValue, 1);
rvalue->type = ConfigRValueType_Integer; rvalue->type = ConfigRValueType_Integer;
if (value.is_signed){ if (value.is_signed){
@ -448,18 +441,18 @@ config_parser__rvalue(Config_Parser *ctx){
rvalue->uinteger = value.uinteger; rvalue->uinteger = value.uinteger;
} }
} }
else if (config_parser__recognize_token(ctx, TokenCppKind_LiteralString)){ else if (def_config_parser_recognize_cpp_kind(ctx, TokenCppKind_LiteralString)){
String_Const_u8 s = config_parser__get_lexeme(ctx); String_Const_u8 s = def_config_parser_get_lexeme(ctx);
config_parser__advance_to_next(ctx); def_config_parser_inc(ctx);
s = string_chop(string_skip(s, 1), 1); s = string_chop(string_skip(s, 1), 1);
String_Const_u8 interpreted = string_interpret_escapes(ctx->arena, s); String_Const_u8 interpreted = string_interpret_escapes(ctx->arena, s);
rvalue = push_array_zero(ctx->arena, Config_RValue, 1); rvalue = push_array_zero(ctx->arena, Config_RValue, 1);
rvalue->type = ConfigRValueType_String; rvalue->type = ConfigRValueType_String;
rvalue->string = interpreted; rvalue->string = interpreted;
} }
else if (config_parser__recognize_token(ctx, TokenCppKind_LiteralCharacter)){ else if (def_config_parser_recognize_cpp_kind(ctx, TokenCppKind_LiteralCharacter)){
String_Const_u8 s = config_parser__get_lexeme(ctx); String_Const_u8 s = def_config_parser_get_lexeme(ctx);
config_parser__advance_to_next(ctx); def_config_parser_inc(ctx);
s = string_chop(string_skip(s, 1), 1); s = string_chop(string_skip(s, 1), 1);
String_Const_u8 interpreted = string_interpret_escapes(ctx->arena, s); String_Const_u8 interpreted = string_interpret_escapes(ctx->arena, s);
rvalue = push_array_zero(ctx->arena, Config_RValue, 1); rvalue = push_array_zero(ctx->arena, Config_RValue, 1);
@ -479,34 +472,34 @@ config_parser__compound__check(Config_Parser *ctx, Config_Compound *compound){
implicit_index_allowed = false; implicit_index_allowed = false;
} }
else if (!implicit_index_allowed){ else if (!implicit_index_allowed){
config_parser__log_error_pos(ctx, node->l.pos, def_config_parser_push_error(ctx, node->l.pos,
"encountered unlabeled member after one or more labeled members"); "encountered unlabeled member after one or more labeled members");
} }
} }
} }
function Config_Compound* function Config_Compound*
config_parser__compound(Config_Parser *ctx){ def_config_parser_compound(Config_Parser *ctx){
Config_Compound_Element *first = 0; Config_Compound_Element *first = 0;
Config_Compound_Element *last = 0; Config_Compound_Element *last = 0;
i32 count = 0; i32 count = 0;
Config_Compound_Element *element = config_parser__element(ctx); Config_Compound_Element *element = def_config_parser_element(ctx);
require(element != 0); require(element != 0);
zdll_push_back(first, last, element); zdll_push_back(first, last, element);
count += 1; count += 1;
for (;config_parser__match_token(ctx, TokenCppKind_Comma);){ for (;def_config_parser_match_cpp_kind(ctx, TokenCppKind_Comma);){
if (config_parser__recognize_token(ctx, TokenCppKind_BraceCl)){ if (def_config_parser_recognize_cpp_kind(ctx, TokenCppKind_BraceCl)){
break; break;
} }
element = config_parser__element(ctx); element = def_config_parser_element(ctx);
require(element != 0); require(element != 0);
zdll_push_back(first, last, element); zdll_push_back(first, last, element);
count += 1; count += 1;
} }
require(config_parser__match_token(ctx, TokenCppKind_BraceCl)); require(def_config_parser_match_cpp_kind(ctx, TokenCppKind_BraceCl));
Config_Compound *compound = push_array(ctx->arena, Config_Compound, 1); Config_Compound *compound = push_array(ctx->arena, Config_Compound, 1);
block_zero_struct(compound); block_zero_struct(compound);
@ -518,27 +511,27 @@ config_parser__compound(Config_Parser *ctx){
} }
function Config_Compound_Element* function Config_Compound_Element*
config_parser__element(Config_Parser *ctx){ def_config_parser_element(Config_Parser *ctx){
Config_Layout layout = {}; Config_Layout layout = {};
layout.pos = config_parser__get_pos(ctx); layout.pos = def_config_parser_get_pos(ctx);
if (config_parser__match_token(ctx, TokenCppKind_Dot)){ if (def_config_parser_match_cpp_kind(ctx, TokenCppKind_Dot)){
if (config_parser__recognize_token(ctx, TokenCppKind_Identifier)){ if (def_config_parser_recognize_cpp_kind(ctx, TokenCppKind_Identifier)){
layout.type = ConfigLayoutType_Identifier; layout.type = ConfigLayoutType_Identifier;
layout.identifier = config_parser__get_lexeme(ctx); layout.identifier = def_config_parser_get_lexeme(ctx);
config_parser__advance_to_next(ctx); def_config_parser_inc(ctx);
} }
else if (config_parser__recognize_base_token(ctx, TokenBaseKind_LiteralInteger)){ else if (def_config_parser_recognize_base_kind(ctx, TokenBaseKind_LiteralInteger)){
layout.type = ConfigLayoutType_Integer; layout.type = ConfigLayoutType_Integer;
Config_Integer value = config_parser__get_int(ctx); Config_Integer value = def_config_parser_get_int(ctx);
layout.integer = value.integer; layout.integer = value.integer;
config_parser__advance_to_next(ctx); def_config_parser_inc(ctx);
} }
else{ else{
return(0); return(0);
} }
require(config_parser__match_token(ctx, TokenCppKind_Eq)); require(def_config_parser_match_cpp_kind(ctx, TokenCppKind_Eq));
} }
Config_RValue *rvalue = config_parser__rvalue(ctx); Config_RValue *rvalue = def_config_parser_rvalue(ctx);
require(rvalue != 0); require(rvalue != 0);
Config_Compound_Element *element = push_array(ctx->arena, Config_Compound_Element, 1); Config_Compound_Element *element = push_array(ctx->arena, Config_Compound_Element, 1);
block_zero_struct(element); block_zero_struct(element);
@ -549,10 +542,10 @@ config_parser__element(Config_Parser *ctx){
//////////////////////////////// ////////////////////////////////
// TODO(allen): WHAT THE HELL IS THIS SHIT?
function Config_Error* function Config_Error*
config_add_error(Arena *arena, Config *config, u8 *pos, char *error_text){ config_add_error(Arena *arena, Config *config, u8 *pos, char *error_text){
return(config_error_push(arena, &config->errors, config->file_name, pos, return(def_config_push_error(arena, &config->errors, config->file_name, pos, error_text));
error_text));
} }
//////////////////////////////// ////////////////////////////////
@ -1206,7 +1199,7 @@ config_from_text(Application_Links *app, Arena *arena, String_Const_u8 file_name
Temp_Memory restore_point = begin_temp(arena); Temp_Memory restore_point = begin_temp(arena);
Token_Array array = token_array_from_text(app, arena, data); Token_Array array = token_array_from_text(app, arena, data);
if (array.tokens != 0){ if (array.tokens != 0){
parsed = config_parse(app, arena, file_name, data, array); parsed = def_config_parse(app, arena, file_name, data, array);
if (parsed == 0){ if (parsed == 0){
end_temp(restore_point); end_temp(restore_point);
} }

View File

@ -7,10 +7,11 @@
#if !defined(FCODER_CONFIG_H) #if !defined(FCODER_CONFIG_H)
#define FCODER_CONFIG_H #define FCODER_CONFIG_H
// TODO(allen): Stop handling files this way! My own API should be able to do this!!?!?!?!!?!?!!!!?
// NOTE(allen): Actually need binary buffers for some stuff to work, but not this parsing thing here.
#include <stdio.h> #include <stdio.h>
////////////////////////////////
// NOTE(allen): Config Parser Types
struct Error_Location{ struct Error_Location{
i32 line_number; i32 line_number;
i32 column_number; i32 column_number;
@ -31,9 +32,8 @@ struct Config_Error_List{
}; };
struct Config_Parser{ struct Config_Parser{
Token *start;
Token *token; Token *token;
Token *end; Token *opl;
String_Const_u8 file_name; String_Const_u8 file_name;
String_Const_u8 data; String_Const_u8 data;
@ -138,6 +138,7 @@ struct Config{
}; };
//////////////////////////////// ////////////////////////////////
// NOTE(allen): Config Iteration
typedef i32 Iteration_Step_Result; typedef i32 Iteration_Step_Result;
enum{ enum{
@ -178,6 +179,7 @@ struct Config_Get_Result_List{
}; };
//////////////////////////////// ////////////////////////////////
// NOTE(allen): Config Data Type
struct Config_Data{ struct Config_Data{
u8 user_name_space[256]; u8 user_name_space[256];
@ -246,6 +248,40 @@ struct Config_Data{
b8 lalt_lctrl_is_altgr; b8 lalt_lctrl_is_altgr;
}; };
////////////////////////////////
// NOTE(allen): Config Parser Functions
function Config_Parser def_config_parser_init(Arena *arena, String_Const_u8 file_name, String_Const_u8 data, Token_Array array);
function void def_config_parser_inc(Config_Parser *ctx);
function u8* def_config_parser_get_pos(Config_Parser *ctx);
function b32 def_config_parser_recognize_base_kind(Config_Parser *ctx, Token_Base_Kind kind);
function b32 def_config_parser_recognize_cpp_kind(Config_Parser *ctx, Token_Cpp_Kind kind);
function b32 def_config_parser_recognize_boolean(Config_Parser *ctx);
function b32 def_config_parser_recognize_text(Config_Parser *ctx, String_Const_u8 text);
function b32 def_config_parser_match_cpp_kind(Config_Parser *ctx, Token_Cpp_Kind kind);
function b32 def_config_parser_match_text(Config_Parser *ctx, String_Const_u8 text);
function String_Const_u8 def_config_parser_get_lexeme(Config_Parser *ctx);
function Config_Integer def_config_parser_get_int(Config_Parser *ctx);
function b32 def_config_parser_get_boolean(Config_Parser *ctx);
function Config* def_config_parser_config (Config_Parser *ctx);
function i32* def_config_parser_version (Config_Parser *ctx);
function Config_Assignment* def_config_parser_assignment(Config_Parser *ctx);
function Config_LValue* def_config_parser_lvalue (Config_Parser *ctx);
function Config_RValue* def_config_parser_rvalue (Config_Parser *ctx);
function Config_Compound* def_config_parser_compound (Config_Parser *ctx);
function Config_Compound_Element* def_config_parser_element (Config_Parser *ctx);
function Config* def_config_parse(Application_Links *app, Arena *arena, String_Const_u8 file_name, String_Const_u8 data, Token_Array array);
function Config_Error* def_config_push_error(Arena *arena, Config_Error_List *list, String_Const_u8 file_name, u8 *pos, char *error_text);
function void def_config_parser_push_error(Config_Parser *ctx, u8 *pos, char *error_text);
function void def_config_parser_push_error_here(Config_Parser *ctx, char *error_text);
#endif #endif
// BOTTOM // BOTTOM

View File

@ -30,11 +30,13 @@
#include "generated/command_metadata.h" #include "generated/command_metadata.h"
#endif #endif
#include "4coder_token.h"
#include "generated/lexer_cpp.h"
#include "4coder_variables.h" #include "4coder_variables.h"
#include "4coder_audio.h" #include "4coder_audio.h"
#include "4coder_profile.h" #include "4coder_profile.h"
#include "4coder_async_tasks.h" #include "4coder_async_tasks.h"
#include "4coder_token.h"
#include "4coder_string_match.h" #include "4coder_string_match.h"
#include "4coder_helper.h" #include "4coder_helper.h"
#include "4coder_delta_rule.h" #include "4coder_delta_rule.h"
@ -68,7 +70,6 @@
#include "4coder_stringf.cpp" #include "4coder_stringf.cpp"
#include "4coder_app_links_allocator.cpp" #include "4coder_app_links_allocator.cpp"
#include "4coder_system_allocator.cpp" #include "4coder_system_allocator.cpp"
#include "generated/lexer_cpp.h"
#include "4coder_file.cpp" #include "4coder_file.cpp"

View File

@ -445,7 +445,7 @@ parse_project__data(Application_Links *app, Arena *arena, String_Const_u8 file_n
Project_Parse_Result result = {}; Project_Parse_Result result = {};
Token_Array array = token_array_from_text(app, arena, data); Token_Array array = token_array_from_text(app, arena, data);
if (array.tokens != 0){ if (array.tokens != 0){
result.parsed = config_parse(app, arena, file_name, data, array); result.parsed = def_config_parse(app, arena, file_name, data, array);
if (result.parsed != 0){ if (result.parsed != 0){
result.project = parse_project__config_data(app, arena, file_dir, result.project = parse_project__config_data(app, arena, file_dir,
result.parsed); result.parsed);

View File

@ -372,7 +372,7 @@ static Command_Metadata fcoder_metacmd_table[250] = {
{ PROC_LINKS(list_all_substring_locations, 0), false, "list_all_substring_locations", 28, "Queries the user for a string and lists all case-sensitive substring matches found in all open buffers.", 103, "W:\\4ed\\code\\custom\\4coder_search.cpp", 36, 174 }, { PROC_LINKS(list_all_substring_locations, 0), false, "list_all_substring_locations", 28, "Queries the user for a string and lists all case-sensitive substring matches found in all open buffers.", 103, "W:\\4ed\\code\\custom\\4coder_search.cpp", 36, 174 },
{ PROC_LINKS(list_all_substring_locations_case_insensitive, 0), false, "list_all_substring_locations_case_insensitive", 45, "Queries the user for a string and lists all case-insensitive substring matches found in all open buffers.", 105, "W:\\4ed\\code\\custom\\4coder_search.cpp", 36, 186 }, { PROC_LINKS(list_all_substring_locations_case_insensitive, 0), false, "list_all_substring_locations_case_insensitive", 45, "Queries the user for a string and lists all case-insensitive substring matches found in all open buffers.", 105, "W:\\4ed\\code\\custom\\4coder_search.cpp", 36, 186 },
{ PROC_LINKS(load_project, 0), false, "load_project", 12, "Looks for a project.4coder file in the current directory and tries to load it. Looks in parent directories until a project file is found or there are no more parents.", 167, "W:\\4ed\\code\\custom\\4coder_project_commands.cpp", 46, 867 }, { PROC_LINKS(load_project, 0), false, "load_project", 12, "Looks for a project.4coder file in the current directory and tries to load it. Looks in parent directories until a project file is found or there are no more parents.", 167, "W:\\4ed\\code\\custom\\4coder_project_commands.cpp", 46, 867 },
{ PROC_LINKS(load_theme_current_buffer, 0), false, "load_theme_current_buffer", 25, "Parse the current buffer as a theme file and add the theme to the theme list. If the buffer has a .4coder postfix in it's name, it is removed when the name is saved.", 165, "W:\\4ed\\code\\custom\\4coder_config.cpp", 36, 1667 }, { PROC_LINKS(load_theme_current_buffer, 0), false, "load_theme_current_buffer", 25, "Parse the current buffer as a theme file and add the theme to the theme list. If the buffer has a .4coder postfix in it's name, it is removed when the name is saved.", 165, "W:\\4ed\\code\\custom\\4coder_config.cpp", 36, 1660 },
{ PROC_LINKS(load_themes_default_folder, 0), false, "load_themes_default_folder", 26, "Loads all the theme files in the default theme folder.", 54, "W:\\4ed\\code\\custom\\4coder_default_framework.cpp", 47, 533 }, { PROC_LINKS(load_themes_default_folder, 0), false, "load_themes_default_folder", 26, "Loads all the theme files in the default theme folder.", 54, "W:\\4ed\\code\\custom\\4coder_default_framework.cpp", 47, 533 },
{ PROC_LINKS(load_themes_hot_directory, 0), false, "load_themes_hot_directory", 25, "Loads all the theme files in the current hot directory.", 55, "W:\\4ed\\code\\custom\\4coder_default_framework.cpp", 47, 545 }, { PROC_LINKS(load_themes_hot_directory, 0), false, "load_themes_hot_directory", 25, "Loads all the theme files in the current hot directory.", 55, "W:\\4ed\\code\\custom\\4coder_default_framework.cpp", 47, 545 },
{ PROC_LINKS(make_directory_query, 0), false, "make_directory_query", 20, "Queries the user for a name and creates a new directory with the given name.", 76, "W:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1493 }, { PROC_LINKS(make_directory_query, 0), false, "make_directory_query", 20, "Queries the user for a name and creates a new directory with the given name.", 76, "W:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1493 },