From 9491fdf5c240878d0e38d5824f207976e70b8e49 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Fri, 26 Jun 2026 11:22:43 -0600 Subject: [PATCH] eval2: split out expression kinds from parse styles of expressions - lets us separate semantic expression tree from frontend, so that we can easily switch frontend --- src/eval2/eval2.c | 133 +++++++++++++++++++------------ src/eval2/eval2.h | 21 ++--- src/eval2/eval2.mdesk | 109 ++++++++++++++++++++----- src/eval2/generated/eval2.meta.c | 81 +++++++++---------- src/eval2/generated/eval2.meta.h | 27 ++++++- src/scratch/ryan_scratch.c | 2 +- 6 files changed, 239 insertions(+), 134 deletions(-) diff --git a/src/eval2/eval2.c b/src/eval2/eval2.c index 1abf8ded..5b528e45 100644 --- a/src/eval2/eval2.c +++ b/src/eval2/eval2.c @@ -1508,8 +1508,9 @@ e2_irnode_push_child(Arena *arena, E2_IRNode *parent, E2_IRNode *expr) //~ rjf: String -> Expression internal E2_Token -e2_token_from_string_off(String8 string, U64 start_off) +e2_token_from_string_off(E2_LangKind lang, String8 string, U64 start_off) { + E2_LangInfo *lang_info = &e2_lang_kind_info_table[lang]; E2_Token token = {E2_TokenKind_Null}; B32 identifier_tick_mode = 0; B32 comment_is_explicit_ender = 0; @@ -1648,9 +1649,9 @@ e2_token_from_string_off(String8 string, U64 start_off) token.range.max = off; String8 token_string = str8_substr(string, token.range); U64 biggest_match_size = 0; - for EachNonZeroEnumVal(E2_ExprKind, k) + for EachIndex(idx, lang_info->expr_kind_parse_infos_count) { - String8 op_symbol = (e2_expr_kind_info_table[k].pre.size != 0) ? e2_expr_kind_info_table[k].pre : e2_expr_kind_info_table[k].sep; + String8 op_symbol = (lang_info->expr_kind_parse_infos[idx].pre.size != 0) ? lang_info->expr_kind_parse_infos[idx].pre : lang_info->expr_kind_parse_infos[idx].sep; if(biggest_match_size < op_symbol.size && str8_match(op_symbol, str8_prefix(token_string, op_symbol.size), 0)) { biggest_match_size = op_symbol.size; @@ -1695,9 +1696,9 @@ e2_token_from_string_off(String8 string, U64 start_off) } internal U64 -e2_read_token(String8 string, U64 off, E2_Token *token_out) +e2_read_token(E2_LangKind lang, String8 string, U64 off, E2_Token *token_out) { - E2_Token token = e2_token_from_string_off(string, off); + E2_Token token = e2_token_from_string_off(lang, string, off); if(token_out != 0) { token_out[0] = token; @@ -1707,14 +1708,14 @@ e2_read_token(String8 string, U64 off, E2_Token *token_out) } internal B32 -e2_try_token(String8 string, E2_TokenKind kind, String8 expected_string, U64 *off_out, E2_Token *token_out) +e2_try_token(E2_LangKind lang, String8 string, E2_TokenKind kind, String8 expected_string, U64 *off_out, E2_Token *token_out) { B32 result = 0; U64 off = off_out[0]; for(;;) { E2_Token next_token = {E2_TokenKind_Null}; - off += e2_read_token(string, off, &next_token); + off += e2_read_token(lang, string, off, &next_token); if(next_token.kind == kind && (expected_string.size == 0 || str8_match(str8_substr(string, next_token.range), expected_string, 0))) { result = 1; @@ -1737,10 +1738,11 @@ e2_try_token(String8 string, E2_TokenKind kind, String8 expected_string, U64 *of } internal E2_Parse -e2_parse_from_string(Arena *arena, E2_ParseState *state, B32 identifier_is_type, String8 string) +e2_parse_from_string(Arena *arena, E2_ParseState *state, B32 identifier_is_type, E2_LangKind lang, String8 string) { U64 off = state->string_off; E2_Parse parse = {E2_ParseStatus_Error, .expr = &e2_expr_nil, .params_expr = &e2_expr_nil}; + E2_LangInfo *lang_info = &e2_lang_kind_info_table[lang]; //- rjf: parse & attach to top parsing task - if we don't have a top task // then it is just the result @@ -1756,7 +1758,7 @@ e2_parse_from_string(Arena *arena, E2_ParseState *state, B32 identifier_is_type, for(;;) { E2_Token next_token = {0}; - U64 next_off = off + e2_read_token(string, off, &next_token); + U64 next_off = off + e2_read_token(lang, string, off, &next_token); if(next_token.kind == E2_TokenKind_Whitespace || next_token.kind == E2_TokenKind_Comment) { @@ -1769,7 +1771,7 @@ e2_parse_from_string(Arena *arena, E2_ParseState *state, B32 identifier_is_type, } //- rjf: nested sub-expressions - if(need_new_expr && e2_try_token(string, E2_TokenKind_Symbol, s("("), &off, &token)) + if(need_new_expr && e2_try_token(lang, string, E2_TokenKind_Symbol, s("("), &off, &token)) { E2_ParseTask *task = state->free_task; if(task != 0) @@ -1789,21 +1791,23 @@ e2_parse_from_string(Arena *arena, E2_ParseState *state, B32 identifier_is_type, } //- rjf: symbols (possible prefix unaries, *or* unexpected) - else if(need_new_expr && e2_try_token(string, E2_TokenKind_Symbol, s(""), &off, &token)) + else if(need_new_expr && e2_try_token(lang, string, E2_TokenKind_Symbol, s(""), &off, &token)) { // rjf: string -> operator kind E2_ExprKind expr_kind = E2_ExprKind_Null; String8 closer = {0}; + S64 precedence = 0; { String8 token_string = str8_substr(string, token.range); - for EachNonZeroEnumVal(E2_ExprKind, k) + for EachIndex(idx, lang_info->expr_kind_parse_infos_count) { - if(e2_expr_kind_info_table[k].parse_kind == E2_ExprParseKind_UnaryPrefix && - e2_expr_kind_info_table[k].precedence <= max_precedence && - str8_match(token_string, e2_expr_kind_info_table[k].pre, 0)) + if(lang_info->expr_kind_parse_infos[idx].parse_kind == E2_ExprParseKind_UnaryPrefix && + lang_info->expr_kind_parse_infos[idx].precedence <= max_precedence && + str8_match(token_string, lang_info->expr_kind_parse_infos[idx].pre, 0)) { - expr_kind = k; - closer = e2_expr_kind_info_table[k].post; + expr_kind = lang_info->expr_kind_parse_infos[idx].expr_kind; + closer = lang_info->expr_kind_parse_infos[idx].post; + precedence = lang_info->expr_kind_parse_infos[idx].precedence; break; } } @@ -1825,7 +1829,7 @@ e2_parse_from_string(Arena *arena, E2_ParseState *state, B32 identifier_is_type, task->src_range = token.range; task->child_count_target = 1; task->expr_kind = expr_kind; - task->max_precedence = e2_expr_kind_info_table[expr_kind].precedence; + task->max_precedence = precedence; task->expected_closer = closer; SLLStackPush(state->top_task, task); } @@ -1839,7 +1843,7 @@ e2_parse_from_string(Arena *arena, E2_ParseState *state, B32 identifier_is_type, } //- rjf: identifiers with an active dot op kind -> member access - else if(need_new_expr && state->top_task != 0 && state->top_task->expr_kind == E2_ExprKind_Dot && e2_try_token(string, E2_TokenKind_Identifier, s(""), &off, &token)) + else if(need_new_expr && state->top_task != 0 && state->top_task->expr_kind == E2_ExprKind_Dot && e2_try_token(lang, string, E2_TokenKind_Identifier, s(""), &off, &token)) { expr = e2_expr(arena, E2_ExprKind_Dot); expr->first_child = state->top_task->first_child; @@ -1853,14 +1857,14 @@ e2_parse_from_string(Arena *arena, E2_ParseState *state, B32 identifier_is_type, } //- rjf: standalone identifiers (also could be definition or operator keyword) - else if(need_new_expr && e2_try_token(string, E2_TokenKind_Identifier, s(""), &off, &token)) + else if(need_new_expr && e2_try_token(lang, string, E2_TokenKind_Identifier, s(""), &off, &token)) { String8 identifier = str8_substr(string, token.range); B32 identifier_mapped = 0; B32 definitions_are_allowed = (state->top_task == 0 || state->top_task->expr_kind != E2_ExprKind_Macro); // rjf: first try to resolve as a definition - if(definitions_are_allowed && !identifier_mapped && e2_try_token(string, E2_TokenKind_Symbol, s("="), &off, 0)) + if(definitions_are_allowed && !identifier_mapped && e2_try_token(lang, string, E2_TokenKind_Symbol, s("="), &off, 0)) { identifier_mapped = 1; E2_ParseTask *task = state->free_task; @@ -1876,7 +1880,7 @@ e2_parse_from_string(Arena *arena, E2_ParseState *state, B32 identifier_is_type, task->src_range = token.range; task->child_count_target = 1; task->expr_kind = E2_ExprKind_Define; - task->max_precedence = e2_expr_kind_info_table[E2_ExprKind_Define].precedence; + task->max_precedence = max_S64; task->identifier = identifier; SLLStackPush(state->top_task, task); } @@ -1885,26 +1889,26 @@ e2_parse_from_string(Arena *arena, E2_ParseState *state, B32 identifier_is_type, if(definitions_are_allowed && !identifier_mapped) { U64 macro_off = off; - if(e2_try_token(string, E2_TokenKind_Symbol, s("("), ¯o_off, 0)) + if(e2_try_token(lang, string, E2_TokenKind_Symbol, s("("), ¯o_off, 0)) { U64 post_macro_paren_off = macro_off; B32 looks_like_macro_def = 1; U64 macro_arg_count = 0; for(;macro_off < string.size;) { - if(!e2_try_token(string, E2_TokenKind_Identifier, s(""), ¯o_off, 0)) + if(!e2_try_token(lang, string, E2_TokenKind_Identifier, s(""), ¯o_off, 0)) { looks_like_macro_def = 0; break; } macro_arg_count += 1; - e2_try_token(string, E2_TokenKind_Symbol, s(","), ¯o_off, 0); - if(e2_try_token(string, E2_TokenKind_Symbol, s(")"), ¯o_off, 0)) + e2_try_token(lang, string, E2_TokenKind_Symbol, s(","), ¯o_off, 0); + if(e2_try_token(lang, string, E2_TokenKind_Symbol, s(")"), ¯o_off, 0)) { break; } } - if(looks_like_macro_def && e2_try_token(string, E2_TokenKind_Symbol, s("="), ¯o_off, 0)) + if(looks_like_macro_def && e2_try_token(lang, string, E2_TokenKind_Symbol, s("="), ¯o_off, 0)) { // rjf: push task to fill macro definition identifier_mapped = 1; @@ -1930,18 +1934,18 @@ e2_parse_from_string(Arena *arena, E2_ParseState *state, B32 identifier_is_type, for(;macro_off < string.size;) { E2_Token next_token = {0}; - if(!e2_try_token(string, E2_TokenKind_Identifier, s(""), ¯o_off, &next_token)) + if(!e2_try_token(lang, string, E2_TokenKind_Identifier, s(""), ¯o_off, &next_token)) { break; } str8_list_push(arena, &task->macro_arg_names, str8_substr(string, next_token.range)); - e2_try_token(string, E2_TokenKind_Symbol, s(","), ¯o_off, 0); - if(e2_try_token(string, E2_TokenKind_Symbol, s(")"), ¯o_off, 0)) + e2_try_token(lang, string, E2_TokenKind_Symbol, s(","), ¯o_off, 0); + if(e2_try_token(lang, string, E2_TokenKind_Symbol, s(")"), ¯o_off, 0)) { break; } } - e2_try_token(string, E2_TokenKind_Symbol, s("="), ¯o_off, 0); + e2_try_token(lang, string, E2_TokenKind_Symbol, s("="), ¯o_off, 0); // rjf: advance offset to past '=' off = macro_off; @@ -1954,15 +1958,17 @@ e2_parse_from_string(Arena *arena, E2_ParseState *state, B32 identifier_is_type, { // rjf: string -> op kind E2_ExprKind expr_kind = E2_ExprKind_Null; + S64 precedence = 0; { String8 token_string = str8_substr(string, token.range); - for EachNonZeroEnumVal(E2_ExprKind, k) + for EachIndex(idx, lang_info->expr_kind_parse_infos_count) { - if(e2_expr_kind_info_table[k].parse_kind == E2_ExprParseKind_UnaryPrefix && - e2_expr_kind_info_table[k].precedence <= max_precedence && - str8_match(token_string, str8_skip_chop_whitespace(e2_expr_kind_info_table[k].pre), 0)) + if(lang_info->expr_kind_parse_infos[idx].parse_kind == E2_ExprParseKind_UnaryPrefix && + lang_info->expr_kind_parse_infos[idx].precedence <= max_precedence && + str8_match(token_string, str8_skip_chop_whitespace(lang_info->expr_kind_parse_infos[idx].pre), 0)) { - expr_kind = k; + expr_kind = lang_info->expr_kind_parse_infos[idx].expr_kind; + precedence = lang_info->expr_kind_parse_infos[idx].precedence; break; } } @@ -1985,7 +1991,7 @@ e2_parse_from_string(Arena *arena, E2_ParseState *state, B32 identifier_is_type, task->src_range = token.range; task->child_count_target = 1; task->expr_kind = expr_kind; - task->max_precedence = e2_expr_kind_info_table[expr_kind].precedence; + task->max_precedence = precedence; SLLStackPush(state->top_task, task); } } @@ -2035,14 +2041,14 @@ e2_parse_from_string(Arena *arena, E2_ParseState *state, B32 identifier_is_type, } //- rjf: leaf numerics - else if(need_new_expr && e2_try_token(string, E2_TokenKind_Numeric, s(""), &off, &token)) + else if(need_new_expr && e2_try_token(lang, string, E2_TokenKind_Numeric, s(""), &off, &token)) { expr = e2_expr(arena, E2_ExprKind_Numeric); expr->string = str8_substr(string, token.range); } //- rjf: leaf string literals - else if(need_new_expr && e2_try_token(string, E2_TokenKind_StringLiteral, s(""), &off, &token)) + else if(need_new_expr && e2_try_token(lang, string, E2_TokenKind_StringLiteral, s(""), &off, &token)) { String8 token_string = str8_substr(string, token.range); String8 unquoted_string = str8_skip(str8_chop(token_string, 1), 1); @@ -2052,7 +2058,7 @@ e2_parse_from_string(Arena *arena, E2_ParseState *state, B32 identifier_is_type, } //- rjf: leaf character literals - else if(need_new_expr && e2_try_token(string, E2_TokenKind_CharLiteral, s(""), &off, &token)) + else if(need_new_expr && e2_try_token(lang, string, E2_TokenKind_CharLiteral, s(""), &off, &token)) { String8 token_string = str8_substr(string, token.range); String8 unquoted_string = str8_skip(str8_chop(token_string, 1), 1); @@ -2065,7 +2071,7 @@ e2_parse_from_string(Arena *arena, E2_ParseState *state, B32 identifier_is_type, if(!state->caller_info_completes_task && expr != &e2_expr_nil) { U64 trailing_symbol_off = off; - if(e2_try_token(string, E2_TokenKind_Symbol, s(""), &trailing_symbol_off, &token)) + if(e2_try_token(lang, string, E2_TokenKind_Symbol, s(""), &trailing_symbol_off, &token)) { // rjf: token string -> operator kind E2_ExprKind expr_kind = E2_ExprKind_Null; @@ -2073,11 +2079,12 @@ e2_parse_from_string(Arena *arena, E2_ParseState *state, B32 identifier_is_type, String8 splitter = {0}; String8 closer = {0}; B32 splitter_is_required = 0; + S64 precedence = 0; { String8 token_string = str8_substr(string, token.range); - for EachNonZeroEnumVal(E2_ExprKind, k) + for EachIndex(idx, lang_info->expr_kind_parse_infos_count) { - E2_ExprKindInfo *expr_kind_info = &e2_expr_kind_info_table[k]; + E2_ExprKindParseInfo *expr_kind_info = &lang_info->expr_kind_parse_infos[idx]; if(expr_kind_info->precedence <= max_precedence && str8_match(token_string, expr_kind_info->sep, 0)) { switch(expr_kind_info->parse_kind) @@ -2089,7 +2096,8 @@ e2_parse_from_string(Arena *arena, E2_ParseState *state, B32 identifier_is_type, } splitter = expr_kind_info->chain; closer = expr_kind_info->post; - expr_kind = k; + expr_kind = expr_kind_info->expr_kind; + precedence = expr_kind_info->precedence; break; } } @@ -2112,7 +2120,7 @@ e2_parse_from_string(Arena *arena, E2_ParseState *state, B32 identifier_is_type, task->child_count = 0; task->child_count_target = child_count_target; task->expr_kind = expr_kind; - task->max_precedence = e2_expr_kind_info_table[expr_kind].precedence; + task->max_precedence = precedence; task->expected_splitter = splitter; task->expected_closer = closer; task->splitter_is_required = splitter_is_required; @@ -2144,7 +2152,7 @@ e2_parse_from_string(Arena *arena, E2_ParseState *state, B32 identifier_is_type, state->top_task->expected_splitter.size != 0 && state->top_task->child_count < state->top_task->child_count_target) { - if(!e2_try_token(string, E2_TokenKind_Symbol, state->top_task->expected_splitter, &off, 0) && state->top_task->splitter_is_required) + if(!e2_try_token(lang, string, E2_TokenKind_Symbol, state->top_task->expected_splitter, &off, 0) && state->top_task->splitter_is_required) { e2_msgf(arena, &parse.msgs, r1u64(off, off), "Expected `%S`.", state->top_task->expected_splitter); } @@ -2154,7 +2162,7 @@ e2_parse_from_string(Arena *arena, E2_ParseState *state, B32 identifier_is_type, B32 closer_found = 0; if(!state->caller_info_completes_task && state->top_task->expected_closer.size != 0) { - closer_found = e2_try_token(string, E2_TokenKind_Symbol, state->top_task->expected_closer, &off, 0); + closer_found = e2_try_token(lang, string, E2_TokenKind_Symbol, state->top_task->expected_closer, &off, 0); } //- rjf: determine if first child of a parenthesized sub-expression is a type @@ -2211,7 +2219,7 @@ e2_parse_from_string(Arena *arena, E2_ParseState *state, B32 identifier_is_type, task->child_count = 1; task->child_count_target = 2; task->expr_kind = E2_ExprKind_CCast; - task->max_precedence = e2_expr_kind_info_table[E2_ExprKind_CCast].precedence; + task->max_precedence = 1; SLLStackPush(state->top_task, task); expr = &e2_expr_nil; E2_ExprNode *child_n = push_array(arena, E2_ExprNode, 1); @@ -2304,6 +2312,25 @@ e2_parse_from_string(Arena *arena, E2_ParseState *state, B32 identifier_is_type, { for(E2_ParseTask *t = state->top_task; t != 0; t = t->next) { + String8 symbol = {0}; + if(t->expr_kind != E2_ExprKind_Null) + { + for EachIndex(idx, lang_info->expr_kind_parse_infos_count) + { + if(lang_info->expr_kind_parse_infos[idx].expr_kind == t->expr_kind) + { + if(lang_info->expr_kind_parse_infos[idx].parse_kind == E2_ExprParseKind_Binary) + { + symbol = lang_info->expr_kind_parse_infos[idx].sep; + } + else if(lang_info->expr_kind_parse_infos[idx].parse_kind == E2_ExprParseKind_UnaryPrefix) + { + symbol = lang_info->expr_kind_parse_infos[idx].pre; + } + break; + } + } + } if(t->child_count == 1 && t->child_count_target == 2 && t->expr_kind == E2_ExprKind_Dot) { e2_msgf(arena, &parse.msgs, t->src_range, "Couldn't access member `%S`.", state->last_requested_member_name); @@ -2316,13 +2343,13 @@ e2_parse_from_string(Arena *arena, E2_ParseState *state, B32 identifier_is_type, { e2_msgf(arena, &parse.msgs, t->src_range, "Couldn't call into this type."); } - else if(t->child_count == 1 && t->child_count_target == 2 && t->expr_kind != E2_ExprKind_Null) + else if(t->child_count == 1 && t->child_count_target == 2 && t->expr_kind != E2_ExprKind_Null && symbol.size != 0) { - e2_msgf(arena, &parse.msgs, t->src_range, "Expected expression after binary operator `%S`.", e2_expr_kind_info_table[t->expr_kind].sep); + e2_msgf(arena, &parse.msgs, t->src_range, "Expected expression after binary operator `%S`.", symbol); } - else if(t->child_count == 0 && t->child_count_target == 1 && t->expr_kind != E2_ExprKind_Null) + else if(t->child_count == 0 && t->child_count_target == 1 && t->expr_kind != E2_ExprKind_Null && symbol.size != 0) { - e2_msgf(arena, &parse.msgs, t->src_range, "Expected expression after unary operator `%S`.", e2_expr_kind_info_table[t->expr_kind].pre); + e2_msgf(arena, &parse.msgs, t->src_range, "Expected expression after unary operator `%S`.", symbol); } else { @@ -2954,7 +2981,7 @@ e2_compile_from_expr(Arena *arena, E2_CompileState *state, E2_IRNode *resolve_re } else { - e2_msgf(arena, &compile.msgs, e->src_range, "Cannot use `%S` on types.", str8_skip_chop_whitespace(e2_expr_kind_info_table[e->kind].sep)); + e2_msgf(arena, &compile.msgs, e->src_range, "Cannot use this operator on types."); } }break; } diff --git a/src/eval2/eval2.h b/src/eval2/eval2.h index e71bd30e..758a43ac 100644 --- a/src/eval2/eval2.h +++ b/src/eval2/eval2.h @@ -5,7 +5,7 @@ #define EVAL2_H //////////////////////////////// -//~ rjf: Operator Info Tables +//~ rjf: Expression Parse Info Table Types typedef enum E2_ExprParseKind { @@ -18,17 +18,6 @@ typedef enum E2_ExprParseKind } E2_ExprParseKind; -typedef struct E2_ExprKindInfo E2_ExprKindInfo; -struct E2_ExprKindInfo -{ - E2_ExprParseKind parse_kind; - S64 precedence; - String8 pre; - String8 sep; - String8 post; - String8 chain; -}; - //////////////////////////////// //~ rjf: Generated Code @@ -674,10 +663,10 @@ internal void e2_irnode_push_child(Arena *arena, E2_IRNode *parent, E2_IRNode *e //////////////////////////////// //~ rjf: String -> Expression -internal E2_Token e2_token_from_string_off(String8 string, U64 start_off); -internal U64 e2_read_token(String8 string, U64 off, E2_Token *token_out); -internal B32 e2_try_token(String8 string, E2_TokenKind kind, String8 expected_string, U64 *off_out, E2_Token *token_out); -internal E2_Parse e2_parse_from_string(Arena *arena, E2_ParseState *state, B32 identifier_is_type, String8 string); +internal E2_Token e2_token_from_string_off(E2_LangKind lang, String8 string, U64 start_off); +internal U64 e2_read_token(E2_LangKind lang, String8 string, U64 off, E2_Token *token_out); +internal B32 e2_try_token(E2_LangKind lang, String8 string, E2_TokenKind kind, String8 expected_string, U64 *off_out, E2_Token *token_out); +internal E2_Parse e2_parse_from_string(Arena *arena, E2_ParseState *state, B32 identifier_is_type, E2_LangKind lang, String8 string); //////////////////////////////// //~ rjf: Expression -> IR Tree diff --git a/src/eval2/eval2.mdesk b/src/eval2/eval2.mdesk index dc77b61c..ef0aaba9 100644 --- a/src/eval2/eval2.mdesk +++ b/src/eval2/eval2.mdesk @@ -1,16 +1,95 @@ // Copyright (c) Epic Games Tools // Licensed under the MIT license (https://opensource.org/license/mit/) -@table(name parse_kind precedence pre sep pos chain) +@table(name) E2_ExprKindTable: { - {Identifier Null 0} - {MacroArg Null 0} - {TypeIdentifier Null 0} - {Numeric Null 0} - {StringLiteral Null 0} - {CharLiteral Null 0} - {Dot Null 0 "" "." "" "" } + {Identifier} + {MacroArg} + {TypeIdentifier} + {Numeric} + {StringLiteral} + {CharLiteral} + {Dot} + {Index} + {Call} + {DerefAsm} + {SizeOf} + {TypeOf} + {CCast} + {Deref} + {Address} + {Pos} + {Neg} + {LogNot} + {BitNot} + {Ptr} + {Mul} + {Div} + {Mod} + {Add} + {Sub} + {LShift} + {RShift} + {Less} + {LtEq} + {Grtr} + {GrEq} + {EqEq} + {NtEq} + {BitAnd} + {BitXor} + {BitOr} + {LogAnd} + {LogOr} + {Define} + {Macro} + {Cond} +} + +@enum E2_ExprKind: +{ + Null, + @expand(E2_ExprKindTable a) `$(a.name)`, + COUNT, +} + +@struct E2_ExprKindParseInfo: +{ + `E2_ExprKind expr_kind`; + `E2_ExprParseKind parse_kind`; + `S64 precedence`; + `String8 pre`; + `String8 sep`; + `String8 post`; + `String8 chain`; +} + +@table(name name_lower) +E2_LangKindTable: +{ + {CLike clike} +} + +@enum E2_LangKind: +{ + @expand(E2_LangKindTable a) `$(a.name)` +} + +@struct E2_LangInfo: +{ + `U64 expr_kind_parse_infos_count`; + `E2_ExprKindParseInfo *expr_kind_parse_infos`; +} + +@data(E2_LangInfo) e2_lang_kind_info_table: +{ + @expand(E2_LangKindTable a) `{ArrayCount(e2_expr_kind_parse_info_table__$(a.name_lower)), (e2_expr_kind_parse_info_table__$(a.name_lower))}` +} + +@table(name parse_kind precedence pre sep pos chain) +E2_ExprKindParseInfoTable_CLike: +{ {Index Binary 1 "" "[" "]" "" } {Call Call 1 "" "(" ")" ","} {DerefAsm UnaryPrefix 1 "[" "" "]" "" } @@ -42,22 +121,12 @@ E2_ExprKindTable: {BitOr Binary 10 "" "|" "" "" } {LogAnd Binary 11 "" "&&" "" "" } {LogOr Binary 12 "" "||" "" "" } - {Define Null 13 "" "=" "" "" } - {Macro Null 14 "" "" "" "" } {Cond Ternary 14 "" "?" "" ":"} } -@enum E2_ExprKind: +@data(E2_ExprKindParseInfo) e2_expr_kind_parse_info_table__clike: { - Null, - @expand(E2_ExprKindTable a) `$(a.name)`, - COUNT, -} - -@data(E2_ExprKindInfo) e2_expr_kind_info_table: -{ - `{0}`, - @expand(E2_ExprKindTable a) `{E2_ExprParseKind_$(a.parse_kind), $(a.precedence), str8_lit_comp("$(a.pre)"), str8_lit_comp("$(a.sep)"), str8_lit_comp("$(a.pos)"), str8_lit_comp("$(a.chain)")}` + @expand(E2_ExprKindParseInfoTable_CLike a) `{E2_ExprKind_$(a.name), E2_ExprParseKind_$(a.parse_kind), $(a.precedence), str8_lit_comp("$(a.pre)"), str8_lit_comp("$(a.sep)"), str8_lit_comp("$(a.pos)"), str8_lit_comp("$(a.chain)")}` } @table(name basic_string basic_byte_size) diff --git a/src/eval2/generated/eval2.meta.c b/src/eval2/generated/eval2.meta.c index d36bd2f9..8df3c611 100644 --- a/src/eval2/generated/eval2.meta.c +++ b/src/eval2/generated/eval2.meta.c @@ -4,50 +4,45 @@ //- GENERATED CODE C_LINKAGE_BEGIN -E2_ExprKindInfo e2_expr_kind_info_table[42] = +E2_LangInfo e2_lang_kind_info_table[1] = { -{0}, -{E2_ExprParseKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("")}, -{E2_ExprParseKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("")}, -{E2_ExprParseKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("")}, -{E2_ExprParseKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("")}, -{E2_ExprParseKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("")}, -{E2_ExprParseKind_Null, 0, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("")}, -{E2_ExprParseKind_Null, 0, str8_lit_comp(""), str8_lit_comp("."), str8_lit_comp(""), str8_lit_comp("")}, -{E2_ExprParseKind_Binary, 1, str8_lit_comp(""), str8_lit_comp("["), str8_lit_comp("]"), str8_lit_comp("")}, -{E2_ExprParseKind_Call, 1, str8_lit_comp(""), str8_lit_comp("("), str8_lit_comp(")"), str8_lit_comp(",")}, -{E2_ExprParseKind_UnaryPrefix, 1, str8_lit_comp("["), str8_lit_comp(""), str8_lit_comp("]"), str8_lit_comp("")}, -{E2_ExprParseKind_UnaryPrefix, 1, str8_lit_comp("sizeof "), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("")}, -{E2_ExprParseKind_UnaryPrefix, 1, str8_lit_comp("typeof "), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("")}, -{E2_ExprParseKind_UnaryPrefix, 1, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("")}, -{E2_ExprParseKind_UnaryPrefix, 2, str8_lit_comp("*"), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("")}, -{E2_ExprParseKind_UnaryPrefix, 2, str8_lit_comp("&"), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("")}, -{E2_ExprParseKind_UnaryPrefix, 2, str8_lit_comp("+"), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("")}, -{E2_ExprParseKind_UnaryPrefix, 2, str8_lit_comp("-"), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("")}, -{E2_ExprParseKind_UnaryPrefix, 2, str8_lit_comp("!"), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("")}, -{E2_ExprParseKind_UnaryPrefix, 2, str8_lit_comp("~"), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("")}, -{E2_ExprParseKind_UnaryPostfix, 1, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("*"), str8_lit_comp("")}, -{E2_ExprParseKind_Binary, 3, str8_lit_comp(""), str8_lit_comp("*"), str8_lit_comp(""), str8_lit_comp("")}, -{E2_ExprParseKind_Binary, 3, str8_lit_comp(""), str8_lit_comp("/"), str8_lit_comp(""), str8_lit_comp("")}, -{E2_ExprParseKind_Binary, 3, str8_lit_comp(""), str8_lit_comp("%"), str8_lit_comp(""), str8_lit_comp("")}, -{E2_ExprParseKind_Binary, 4, str8_lit_comp(""), str8_lit_comp("+"), str8_lit_comp(""), str8_lit_comp("")}, -{E2_ExprParseKind_Binary, 4, str8_lit_comp(""), str8_lit_comp("-"), str8_lit_comp(""), str8_lit_comp("")}, -{E2_ExprParseKind_Binary, 5, str8_lit_comp(""), str8_lit_comp("<<"), str8_lit_comp(""), str8_lit_comp("")}, -{E2_ExprParseKind_Binary, 5, str8_lit_comp(""), str8_lit_comp(">>"), str8_lit_comp(""), str8_lit_comp("")}, -{E2_ExprParseKind_Binary, 6, str8_lit_comp(""), str8_lit_comp("<"), str8_lit_comp(""), str8_lit_comp("")}, -{E2_ExprParseKind_Binary, 6, str8_lit_comp(""), str8_lit_comp("<="), str8_lit_comp(""), str8_lit_comp("")}, -{E2_ExprParseKind_Binary, 6, str8_lit_comp(""), str8_lit_comp(">"), str8_lit_comp(""), str8_lit_comp("")}, -{E2_ExprParseKind_Binary, 6, str8_lit_comp(""), str8_lit_comp(">="), str8_lit_comp(""), str8_lit_comp("")}, -{E2_ExprParseKind_Binary, 7, str8_lit_comp(""), str8_lit_comp("=="), str8_lit_comp(""), str8_lit_comp("")}, -{E2_ExprParseKind_Binary, 7, str8_lit_comp(""), str8_lit_comp("!="), str8_lit_comp(""), str8_lit_comp("")}, -{E2_ExprParseKind_Binary, 8, str8_lit_comp(""), str8_lit_comp("&"), str8_lit_comp(""), str8_lit_comp("")}, -{E2_ExprParseKind_Binary, 9, str8_lit_comp(""), str8_lit_comp("^"), str8_lit_comp(""), str8_lit_comp("")}, -{E2_ExprParseKind_Binary, 10, str8_lit_comp(""), str8_lit_comp("|"), str8_lit_comp(""), str8_lit_comp("")}, -{E2_ExprParseKind_Binary, 11, str8_lit_comp(""), str8_lit_comp("&&"), str8_lit_comp(""), str8_lit_comp("")}, -{E2_ExprParseKind_Binary, 12, str8_lit_comp(""), str8_lit_comp("||"), str8_lit_comp(""), str8_lit_comp("")}, -{E2_ExprParseKind_Null, 13, str8_lit_comp(""), str8_lit_comp("="), str8_lit_comp(""), str8_lit_comp("")}, -{E2_ExprParseKind_Null, 14, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("")}, -{E2_ExprParseKind_Ternary, 14, str8_lit_comp(""), str8_lit_comp("?"), str8_lit_comp(""), str8_lit_comp(":")}, +{ArrayCount(e2_expr_kind_parse_info_table__clike), (e2_expr_kind_parse_info_table__clike)}, +}; + +E2_ExprKindParseInfo e2_expr_kind_parse_info_table__clike[32] = +{ +{E2_ExprKind_Index, E2_ExprParseKind_Binary, 1, str8_lit_comp(""), str8_lit_comp("["), str8_lit_comp("]"), str8_lit_comp("")}, +{E2_ExprKind_Call, E2_ExprParseKind_Call, 1, str8_lit_comp(""), str8_lit_comp("("), str8_lit_comp(")"), str8_lit_comp(",")}, +{E2_ExprKind_DerefAsm, E2_ExprParseKind_UnaryPrefix, 1, str8_lit_comp("["), str8_lit_comp(""), str8_lit_comp("]"), str8_lit_comp("")}, +{E2_ExprKind_SizeOf, E2_ExprParseKind_UnaryPrefix, 1, str8_lit_comp("sizeof "), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("")}, +{E2_ExprKind_TypeOf, E2_ExprParseKind_UnaryPrefix, 1, str8_lit_comp("typeof "), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("")}, +{E2_ExprKind_CCast, E2_ExprParseKind_UnaryPrefix, 1, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("")}, +{E2_ExprKind_Deref, E2_ExprParseKind_UnaryPrefix, 2, str8_lit_comp("*"), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("")}, +{E2_ExprKind_Address, E2_ExprParseKind_UnaryPrefix, 2, str8_lit_comp("&"), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("")}, +{E2_ExprKind_Pos, E2_ExprParseKind_UnaryPrefix, 2, str8_lit_comp("+"), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("")}, +{E2_ExprKind_Neg, E2_ExprParseKind_UnaryPrefix, 2, str8_lit_comp("-"), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("")}, +{E2_ExprKind_LogNot, E2_ExprParseKind_UnaryPrefix, 2, str8_lit_comp("!"), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("")}, +{E2_ExprKind_BitNot, E2_ExprParseKind_UnaryPrefix, 2, str8_lit_comp("~"), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("")}, +{E2_ExprKind_Ptr, E2_ExprParseKind_UnaryPostfix, 1, str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp("*"), str8_lit_comp("")}, +{E2_ExprKind_Mul, E2_ExprParseKind_Binary, 3, str8_lit_comp(""), str8_lit_comp("*"), str8_lit_comp(""), str8_lit_comp("")}, +{E2_ExprKind_Div, E2_ExprParseKind_Binary, 3, str8_lit_comp(""), str8_lit_comp("/"), str8_lit_comp(""), str8_lit_comp("")}, +{E2_ExprKind_Mod, E2_ExprParseKind_Binary, 3, str8_lit_comp(""), str8_lit_comp("%"), str8_lit_comp(""), str8_lit_comp("")}, +{E2_ExprKind_Add, E2_ExprParseKind_Binary, 4, str8_lit_comp(""), str8_lit_comp("+"), str8_lit_comp(""), str8_lit_comp("")}, +{E2_ExprKind_Sub, E2_ExprParseKind_Binary, 4, str8_lit_comp(""), str8_lit_comp("-"), str8_lit_comp(""), str8_lit_comp("")}, +{E2_ExprKind_LShift, E2_ExprParseKind_Binary, 5, str8_lit_comp(""), str8_lit_comp("<<"), str8_lit_comp(""), str8_lit_comp("")}, +{E2_ExprKind_RShift, E2_ExprParseKind_Binary, 5, str8_lit_comp(""), str8_lit_comp(">>"), str8_lit_comp(""), str8_lit_comp("")}, +{E2_ExprKind_Less, E2_ExprParseKind_Binary, 6, str8_lit_comp(""), str8_lit_comp("<"), str8_lit_comp(""), str8_lit_comp("")}, +{E2_ExprKind_LtEq, E2_ExprParseKind_Binary, 6, str8_lit_comp(""), str8_lit_comp("<="), str8_lit_comp(""), str8_lit_comp("")}, +{E2_ExprKind_Grtr, E2_ExprParseKind_Binary, 6, str8_lit_comp(""), str8_lit_comp(">"), str8_lit_comp(""), str8_lit_comp("")}, +{E2_ExprKind_GrEq, E2_ExprParseKind_Binary, 6, str8_lit_comp(""), str8_lit_comp(">="), str8_lit_comp(""), str8_lit_comp("")}, +{E2_ExprKind_EqEq, E2_ExprParseKind_Binary, 7, str8_lit_comp(""), str8_lit_comp("=="), str8_lit_comp(""), str8_lit_comp("")}, +{E2_ExprKind_NtEq, E2_ExprParseKind_Binary, 7, str8_lit_comp(""), str8_lit_comp("!="), str8_lit_comp(""), str8_lit_comp("")}, +{E2_ExprKind_BitAnd, E2_ExprParseKind_Binary, 8, str8_lit_comp(""), str8_lit_comp("&"), str8_lit_comp(""), str8_lit_comp("")}, +{E2_ExprKind_BitXor, E2_ExprParseKind_Binary, 9, str8_lit_comp(""), str8_lit_comp("^"), str8_lit_comp(""), str8_lit_comp("")}, +{E2_ExprKind_BitOr, E2_ExprParseKind_Binary, 10, str8_lit_comp(""), str8_lit_comp("|"), str8_lit_comp(""), str8_lit_comp("")}, +{E2_ExprKind_LogAnd, E2_ExprParseKind_Binary, 11, str8_lit_comp(""), str8_lit_comp("&&"), str8_lit_comp(""), str8_lit_comp("")}, +{E2_ExprKind_LogOr, E2_ExprParseKind_Binary, 12, str8_lit_comp(""), str8_lit_comp("||"), str8_lit_comp(""), str8_lit_comp("")}, +{E2_ExprKind_Cond, E2_ExprParseKind_Ternary, 14, str8_lit_comp(""), str8_lit_comp("?"), str8_lit_comp(""), str8_lit_comp(":")}, }; U8 e2_type_kind_basic_byte_size_table[61] = diff --git a/src/eval2/generated/eval2.meta.h b/src/eval2/generated/eval2.meta.h index 8fa788b5..60a92d50 100644 --- a/src/eval2/generated/eval2.meta.h +++ b/src/eval2/generated/eval2.meta.h @@ -53,6 +53,11 @@ E2_ExprKind_Cond, E2_ExprKind_COUNT, } E2_ExprKind; +typedef enum E2_LangKind +{ +E2_LangKind_CLike, +} E2_LangKind; + typedef enum E2_TypeKind { E2_TypeKind_Null, @@ -131,8 +136,28 @@ E2_TypeKind_FirstMeta = E2_TypeKind_MetaExpr, E2_TypeKind_LastMeta = E2_TypeKind_MetaDescription, } E2_TypeKind; +typedef struct E2_ExprKindParseInfo E2_ExprKindParseInfo; +struct E2_ExprKindParseInfo +{ +E2_ExprKind expr_kind; +E2_ExprParseKind parse_kind; +S64 precedence; +String8 pre; +String8 sep; +String8 post; +String8 chain; +}; + +typedef struct E2_LangInfo E2_LangInfo; +struct E2_LangInfo +{ +U64 expr_kind_parse_infos_count; +E2_ExprKindParseInfo *expr_kind_parse_infos; +}; + C_LINKAGE_BEGIN -extern E2_ExprKindInfo e2_expr_kind_info_table[42]; +extern E2_LangInfo e2_lang_kind_info_table[1]; +extern E2_ExprKindParseInfo e2_expr_kind_parse_info_table__clike[32]; extern U8 e2_type_kind_basic_byte_size_table[61]; extern String8 e2_type_kind_basic_string_table[61]; diff --git a/src/scratch/ryan_scratch.c b/src/scratch/ryan_scratch.c index d7875e8a..3c0994de 100644 --- a/src/scratch/ryan_scratch.c +++ b/src/scratch/ryan_scratch.c @@ -91,7 +91,7 @@ entry_point(CmdLine *cmdline) B32 identifier_is_type = 0; for(;;) { - E2_Parse parse = e2_parse_from_string(scratch.arena, &state, identifier_is_type, strings[idx]); + E2_Parse parse = e2_parse_from_string(scratch.arena, &state, identifier_is_type, E2_LangKind_CLike, strings[idx]); identifier_is_type = 0; expr = parse.expr; for EachNode(n, E2_Msg, parse.msgs.first)