From: yu.dongliang <18588496441@163.com> Date: Mon, 25 Aug 2025 04:02:02 +0000 (+0800) Subject: fix: error when 'enum' var in 'switch-case' X-Git-Url: http://baseworks.info/?a=commitdiff_plain;h=be792dd3939a40d7fc664b8e34990696f7316806;p=scf.git fix: error when 'enum' var in 'switch-case' --- diff --git a/examples/enum2.c b/examples/enum2.c new file mode 100644 index 0000000..c21a2bf --- /dev/null +++ b/examples/enum2.c @@ -0,0 +1,30 @@ +int printf(const char* fmt, ...); + +enum { + ANON_0, + ANON_1, + ANON_2 = ANON_1, + ANON_3, +}; + +int main(int argc) +{ + switch (argc) { + case ANON_0: + printf("ANON_0: %d\n", ANON_0); + break; + + case ANON_1: + printf("ANON_1: %d\n", ANON_1); + break; + + case ANON_3: + printf("ANON_3: %d\n", ANON_3); + break; + default: + break; + }; + + printf("%d,%d,%d,%d\n", ANON_0, ANON_1, ANON_2, ANON_3); + return 0; +} diff --git a/parse/scf_dfa_enum.c b/parse/scf_dfa_enum.c index aab35a0..d0bdafd 100644 --- a/parse/scf_dfa_enum.c +++ b/parse/scf_dfa_enum.c @@ -136,8 +136,6 @@ static int _enum_action_var(scf_dfa_t* dfa, scf_vector_t* words, void* data) md->current_v = v; - scf_logi("enum var: '%s', type: %d, size: %d\n", w->text->data, v->type, v->size); - return SCF_DFA_NEXT_WORD; } @@ -198,6 +196,8 @@ static int _enum_action_comma(scf_dfa_t* dfa, scf_vector_t* words, void* data) d->expr_local_flag--; } + scf_logi("enum var: '%s', value: %ld\n", md->current_v->w->text->data, md->current_v->data.i64); + md->current_v = NULL; return SCF_DFA_SWITCH_TO; diff --git a/parse/scf_dfa_switch.c b/parse/scf_dfa_switch.c index fa22c3a..331236a 100644 --- a/parse/scf_dfa_switch.c +++ b/parse/scf_dfa_switch.c @@ -17,6 +17,9 @@ typedef struct { } dfa_switch_data_t; +int _expr_add_var(scf_parse_t* parse, dfa_data_t* d); + + static int _switch_is_end(scf_dfa_t* dfa, void* word) { return 1; @@ -58,7 +61,7 @@ static int _switch_action_lp(scf_dfa_t* dfa, scf_vector_t* words, void* data) dfa_data_t* d = data; assert(!d->expr); - d->expr_local_flag = 1; + d->expr_local_flag++; SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "switch_rp"), SCF_DFA_HOOK_POST); SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "switch_lp_stat"), SCF_DFA_HOOK_POST); @@ -99,7 +102,7 @@ static int _switch_action_rp(scf_dfa_t* dfa, scf_vector_t* words, void* data) scf_node_add_child(sd->_switch, d->expr); d->expr = NULL; - d->expr_local_flag = 0; + assert(--d->expr_local_flag >= 0); SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "switch_end"), SCF_DFA_HOOK_END); @@ -121,7 +124,7 @@ static int _switch_action_case(scf_dfa_t* dfa, scf_vector_t* words, void* data) dfa_switch_data_t* sd = scf_stack_top(s); assert(!d->expr); - d->expr_local_flag = 1; + d->expr_local_flag++; sd->child = scf_node_alloc(w, SCF_OP_CASE, NULL); if (!sd->child) @@ -129,6 +132,8 @@ static int _switch_action_case(scf_dfa_t* dfa, scf_vector_t* words, void* data) scf_node_add_child((scf_node_t*)parse->ast->current_block, sd->child); + SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "switch_colon"), SCF_DFA_HOOK_PRE); + return SCF_DFA_NEXT_WORD; } @@ -165,9 +170,16 @@ static int _switch_action_colon(scf_dfa_t* dfa, scf_vector_t* words, void* data) return SCF_DFA_ERROR; } + dfa_identity_t* id = scf_stack_top(d->current_identities); + + if (id && id->identity) { + if (_expr_add_var(parse, d) < 0) + return SCF_DFA_ERROR; + } + scf_node_add_child(sd->child, d->expr); d->expr = NULL; - d->expr_local_flag = 0; + assert(--d->expr_local_flag >= 0); } else { assert(SCF_OP_DEFAULT == sd->child->type);