fix: error when 'enum' var in 'switch-case'
authoryu.dongliang <18588496441@163.com>
Mon, 25 Aug 2025 04:02:02 +0000 (12:02 +0800)
committeryu.dongliang <18588496441@163.com>
Mon, 25 Aug 2025 04:02:02 +0000 (12:02 +0800)
examples/enum2.c [new file with mode: 0644]
parse/scf_dfa_enum.c
parse/scf_dfa_switch.c

diff --git a/examples/enum2.c b/examples/enum2.c
new file mode 100644 (file)
index 0000000..c21a2bf
--- /dev/null
@@ -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;
+}
index aab35a01151656479ccb1b7719bf30a5afd688a3..d0bdafd302c75457bd4031800c0900cafeeed0ef 100644 (file)
@@ -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;
index fa22c3a29a531a00421045e2afe0b35e4a6c2244..331236ae727e3d755456d5164f7f3eb80108250e 100644 (file)
@@ -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);