support 'typedef' for 'struct, union, array & function pointer'
authoryu.dongliang <18588496441@163.com>
Thu, 16 Jul 2026 07:36:28 +0000 (15:36 +0800)
committeryu.dongliang <18588496441@163.com>
Thu, 16 Jul 2026 07:36:28 +0000 (15:36 +0800)
22 files changed:
core/scf_ast.c
core/scf_ast.h
core/scf_block.c
core/scf_block.h
core/scf_function.h
core/scf_lex_word.h
core/scf_scope.c
core/scf_scope.h
core/scf_type.h
core/scf_variable.h
examples/c_func_ptr_array.c [new file with mode: 0644]
examples/struct_only_declare.c [new file with mode: 0644]
examples/typedef.c [new file with mode: 0644]
examples/typedef_func_ptr.c [new file with mode: 0644]
native/x64/scf_x64_peephole.c
parse/scf_dfa_class.c
parse/scf_dfa_expr.c
parse/scf_dfa_function.c
parse/scf_dfa_type.c
parse/scf_dfa_var.c
parse/scf_parse.c
parse/scf_parse.h

index 1dc0fa4dc726557a2106a465986383110ca1468c..bad662e76df3fa574132a5fb5f3ccf4459a6563c 100644 (file)
@@ -202,6 +202,35 @@ static int _find_var_by_name(scf_node_t* node, void* arg, scf_vector_t* vec)
        return 0;
 }
 
+static int _find_typedef_by_name(scf_node_t* node, void* arg, scf_vector_t* vec)
+{
+       if (SCF_FUNCTION == node->type)
+               return 1;
+
+       if (node->class_flag)
+               return 1;
+
+       if (SCF_OP_BLOCK == node->type) {
+
+               scf_block_t* b = (scf_block_t*)node;
+
+               if (!b->scope)
+                       return 0;
+
+               scf_variable_t* v = scf_scope_find_typedef(b->scope, arg);
+               if (!v)
+                       return 0;
+
+               assert(!v->local_flag && !v->member_flag);
+
+               if (v->static_flag)
+                       return 0;
+
+               return scf_vector_add(vec, v);
+       }
+       return 0;
+}
+
 int scf_ast_find_global_function(scf_function_t** pf, scf_ast_t* ast, char* fname)
 {
        scf_vector_t* vec = scf_vector_alloc();
@@ -300,6 +329,55 @@ int scf_ast_find_global_variable(scf_variable_t** pv, scf_ast_t* ast, char* name
        return 0;
 }
 
+int scf_ast_find_global_typedef(scf_variable_t** pv, scf_ast_t* ast, char* name)
+{
+       scf_vector_t* vec = scf_vector_alloc();
+       if (!vec)
+               return -ENOMEM;
+
+       int ret = scf_node_search_bfs((scf_node_t*)ast->root_block, name, vec, -1, _find_type_by_name);
+       if (ret < 0) {
+               scf_vector_free(vec);
+               return ret;
+       }
+
+       if (0 == vec->size) {
+               *pv = NULL;
+               scf_vector_free(vec);
+               return 0;
+       }
+
+       scf_variable_t* v2 = vec->data[0];
+       scf_variable_t* v;
+       int n = 0;
+       int i;
+       for (i = 0; i < vec->size; i++) {
+               v  =        vec->data[i];
+
+               if (!v->extern_flag) {
+                       v2 = v;
+                       n++;
+               }
+       }
+
+       if (n > 1) {
+               for (i = 0; i < vec->size; i++) {
+                       v  =        vec->data[i];
+
+                       if (!v->extern_flag)
+                               scf_loge("multi-define: '%s' in file: %s, line: %d\n", name, v->w->file->data, v->w->line);
+               }
+
+               scf_vector_free(vec);
+               return -1;
+       }
+
+       *pv = v2;
+
+       scf_vector_free(vec);
+       return 0;
+}
+
 static int _type_check(scf_type_t** pt, scf_vector_t* vec)
 {
        scf_type_t* t2 = vec->data[0];
@@ -394,6 +472,15 @@ int scf_ast_find_variable(scf_variable_t** pv, scf_ast_t* ast, char* name)
        return scf_ast_find_global_variable(pv, ast, name);
 }
 
+int scf_ast_find_typedef(scf_variable_t** pv, scf_ast_t* ast, char* name)
+{
+       *pv = scf_block_find_typedef(ast->current_block, name);
+       if (*pv)
+               return 0;
+
+       return scf_ast_find_global_typedef(pv, ast, name);
+}
+
 int scf_ast_find_type(scf_type_t** pt, scf_ast_t* ast, char* name)
 {
        *pt = scf_block_find_type(ast->current_block, name);
index 55da0d1ae32257cae601b3aefc9cb8f47117ca95..8657eb960e934d1634154b6080f77a2da90dfed8 100644 (file)
@@ -59,11 +59,15 @@ scf_string_t* scf_variable_type_name(scf_ast_t* ast, scf_variable_t* v);
 int scf_ast_find_proper_function (scf_function_t** pf, scf_ast_t* ast, scf_vector_t* fvec, scf_vector_t* argv);
 int scf_ast_find_global_function (scf_function_t** pf, scf_ast_t* ast, char* name);
 int scf_ast_find_global_variable (scf_variable_t** pv, scf_ast_t* ast, char* name);
+
+int scf_ast_find_global_typedef  (scf_variable_t** pv, scf_ast_t* ast, char* name);
 int scf_ast_find_global_type     (scf_type_t**     pt, scf_ast_t* ast, char* name);
 int scf_ast_find_global_type_type(scf_type_t**     pt, scf_ast_t* ast, int   type);
 
 int scf_ast_find_function (scf_function_t** pf, scf_ast_t* ast, char* name);
 int scf_ast_find_variable (scf_variable_t** pv, scf_ast_t* ast, char* name);
+
+int scf_ast_find_typedef  (scf_variable_t** pv, scf_ast_t* ast, char* name);
 int scf_ast_find_type     (scf_type_t**     pt, scf_ast_t* ast, char* name);
 int scf_ast_find_type_type(scf_type_t**     pt, scf_ast_t* ast, int   type);
 
index 3691b63befa27a3f30ec5243e28bdcea6171ba4f..c41d3d2d4e1084c1a8c2ef88944d8fbc440d7759 100644 (file)
@@ -100,6 +100,23 @@ scf_type_t*        scf_block_find_type_type(scf_block_t* b, const int type)
        return NULL;
 }
 
+scf_variable_t* scf_block_find_typedef(scf_block_t* b, const char* name)
+{
+       assert(b);
+       while (b) {
+               if (SCF_OP_BLOCK == b->node.type || SCF_FUNCTION == b->node.type || b->node.type >= SCF_STRUCT) {
+
+                       if (b->scope) {
+                               scf_variable_t* v = scf_scope_find_typedef(b->scope, name);
+                               if (v)
+                                       return v;
+                       }
+               }
+               b = (scf_block_t*)(b->node.parent);
+       }
+       return NULL;
+}
+
 scf_variable_t*        scf_block_find_variable(scf_block_t* b, const char* name)
 {
        assert(b);
index 30d3fd0415df6fd6c38813a8eda837d9ad61a048..41ae89f5877049120ea8b71c02bf51e73b861ee5 100644 (file)
@@ -14,20 +14,20 @@ struct scf_block_s {
 };
 
 
-scf_block_t*   scf_block_alloc(scf_lex_word_t* w);
+scf_block_t*     scf_block_alloc(scf_lex_word_t* w);
 
-scf_block_t*   scf_block_alloc_cstr(const char* name);
+scf_block_t*     scf_block_alloc_cstr(const char* name);
 
-void                   scf_block_free(scf_block_t* b);
+void             scf_block_free(scf_block_t* b);
 
-scf_type_t*            scf_block_find_type(scf_block_t* b, const char* name);
+scf_type_t*      scf_block_find_type     (scf_block_t* b, const char* name);
+scf_type_t*      scf_block_find_type_type(scf_block_t* b, const int type);
+scf_variable_t*  scf_block_find_typedef  (scf_block_t* b, const char* name);
 
-scf_type_t*            scf_block_find_type_type(scf_block_t* b, const int type);
+scf_variable_t*  scf_block_find_variable(scf_block_t* b, const char* name);
 
-scf_variable_t*        scf_block_find_variable(scf_block_t* b, const char* name);
+scf_function_t*  scf_block_find_function(scf_block_t* b, const char* name);
 
-scf_function_t*        scf_block_find_function(scf_block_t* b, const char* name);
-
-scf_label_t*    scf_block_find_label(scf_block_t* b, const char* name);
+scf_label_t*     scf_block_find_label(scf_block_t* b, const char* name);
 
 #endif
index 08b78180f4fd205bf39eceb8d80277298f3c9831..a6558876cb1e8e6c8a9a65780ee557f22a88a190 100644 (file)
@@ -10,6 +10,8 @@ struct scf_function_s {
 
        scf_string_t*     signature;
 
+       scf_vector_t*     typedef_vars;
+
        scf_list_t        list; // for scope
 
        scf_vector_t*     rets; // return values
index 15dfb57da1c61fab312ffe9a751a1d27c19c2e86..71f0edc89ccaf5fd56e4a18e9ee8bef6110656f7 100644 (file)
@@ -170,7 +170,6 @@ enum scf_lex_words
        SCF_LEX_WORD_KEY_VA_START,  // va_start
        SCF_LEX_WORD_KEY_VA_END,    // va_end
 
-       // class
        SCF_LEX_WORD_KEY_CLASS,     // class
        SCF_LEX_WORD_KEY_TYPEDEF,   // typedef
 
index 732b59efc6e8f22247d5bd7368306309d3601da1..07bb36ff602dfb94ae90f033e3081c3948e8f649 100644 (file)
@@ -12,6 +12,13 @@ scf_scope_t* scf_scope_alloc()
                return NULL;
        }
 
+       scope->typedef_vars = scf_vector_alloc();
+       if (!scope->typedef_vars) {
+               scf_vector_free(scope->vars);
+               free(scope);
+               return NULL;
+       }
+
        scf_list_init(&scope->list);
        scf_list_init(&scope->types);
        scf_list_init(&scope->operators);
@@ -20,7 +27,7 @@ scf_scope_t* scf_scope_alloc()
        return scope;
 }
 
-void scf_scope_push_var(scf_scope_t* scope, scf_variable_t* var)
+int scf_scope_push_var(scf_scope_t* scope, scf_variable_t* var)
 {
        scf_vector_add(scope->vars, var);
 }
@@ -87,6 +94,20 @@ scf_type_t*  scf_scope_find_type_type(scf_scope_t* scope, const int type)
        return NULL;
 }
 
+scf_variable_t*        scf_scope_find_typedef(scf_scope_t* scope, const char* name)
+{
+       scf_variable_t* v;
+       int i;
+
+       for (i = 0; i < scope->typedef_vars->size; i++) {
+               v  =        scope->typedef_vars->data[i];
+
+               if (v->w && !strcmp(name, v->w->text->data))
+                       return v;
+       }
+       return NULL;
+}
+
 scf_variable_t*        scf_scope_find_variable(scf_scope_t* scope, const char* name)
 {
        scf_variable_t* v;
index ac823f19b2db20c1c63259ec80b5063d2b2df3d4..288c043072a1f42fc9f032deb8f28dd7e310fe6b 100644 (file)
@@ -10,17 +10,19 @@ struct scf_scope_s
 {
        scf_list_t          list; // scope list
 
-       scf_vector_t*       vars;          // vars in this scope, should not have the same name
-       scf_list_t          types;     // type list in this scope, not define the same type
-       scf_list_t          operators; // operator list in this scope
-       scf_list_t          functions; // function list in this scope
-       scf_list_t          labels;    // label list in this scope
+       scf_vector_t*       vars;             // vars in this scope, should not have the same name
+       scf_list_t          types;        // type list in this scope, not define the same type
+       scf_list_t          operators;    // operator list in this scope
+       scf_list_t          functions;    // function list in this scope
+       scf_list_t          labels;       // label list in this scope
+
+       scf_vector_t*       typedef_vars; // typedef vars for type alias name
 };
 
 scf_scope_t*    scf_scope_alloc();
 void            scf_scope_free(scf_scope_t* scope);
 
-void            scf_scope_push_var (scf_scope_t* scope, scf_variable_t* var);
+int             scf_scope_push_var (scf_scope_t* scope, scf_variable_t* var);
 void            scf_scope_push_type(scf_scope_t* scope, scf_type_t*     t);
 
 void            scf_scope_push_operator(scf_scope_t* scope, scf_function_t* op);
@@ -28,6 +30,7 @@ void            scf_scope_push_function(scf_scope_t* scope, scf_function_t* f);
 
 scf_type_t*     scf_scope_find_type     (scf_scope_t* scope, const char* name);
 scf_type_t*     scf_scope_find_type_type(scf_scope_t* scope, const int   type);
+scf_variable_t* scf_scope_find_typedef  (scf_scope_t* scope, const char* name);
 scf_variable_t* scf_scope_find_variable (scf_scope_t* scope, const char* name);
 scf_function_t* scf_scope_find_function (scf_scope_t* scope, const char* name);
 
index 3ece46b06df740767f10f0fe32d66eb4c7a00878..5f2b70220e28bd671ee1069a30514f3da6378568 100644 (file)
@@ -21,6 +21,8 @@ struct scf_type_s
        scf_scope_t*        scope;
        scf_string_t*       name;
 
+       scf_vector_t*       typedef_vars;
+
        // list for scope's type_list_head
        scf_list_t                      list;
 
index 98806705e47e4e6e92e1f3d7ebc5cbb1b1713da6..aa501f543077dda838d426965f478ed49adf1485 100644 (file)
@@ -60,6 +60,7 @@ struct scf_variable_s {
        uint32_t            static_flag :1;
        uint32_t            extern_flag :1;
        uint32_t            extra_flag  :1;
+       uint32_t            typedef_flag:1;
 
        uint32_t            tmp_flag    :1;
        uint32_t            local_flag  :1;
diff --git a/examples/c_func_ptr_array.c b/examples/c_func_ptr_array.c
new file mode 100644 (file)
index 0000000..cc1441f
--- /dev/null
@@ -0,0 +1,11 @@
+int printf(const char* fmt, ...);
+
+typedef int (*pf_t[2])(const char* fmt, ...);
+
+int main()
+{
+       pf_t pf = {printf, printf};
+
+       pf[0]("hello world\n");
+       return 0;
+}
diff --git a/examples/struct_only_declare.c b/examples/struct_only_declare.c
new file mode 100644 (file)
index 0000000..9c0bf5a
--- /dev/null
@@ -0,0 +1,11 @@
+int printf(const char* fmt, ...);
+
+struct a_s;
+
+int main()
+{
+       a_s* p = NULL;
+
+       printf("a_s* p: %p\n", p);
+       return 0;
+}
diff --git a/examples/typedef.c b/examples/typedef.c
new file mode 100644 (file)
index 0000000..a993299
--- /dev/null
@@ -0,0 +1,21 @@
+int printf(const char* fmt, ...);
+
+typedef struct a_s {
+       int x;
+} a_t, *a_p;
+
+typedef a_t a2_t[2];
+
+typedef int* intptr;
+
+int main()
+{
+       a2_t a = {{1}, {2}};
+       a_p  p = &a[1];
+
+       int i = 3;
+       intptr pi = &i;
+
+       printf("typedef p: %p, p->x: %d, pi: %p, *pi: %d\n", p, p->x, pi, *pi);
+       return 0;
+}
diff --git a/examples/typedef_func_ptr.c b/examples/typedef_func_ptr.c
new file mode 100644 (file)
index 0000000..f701a67
--- /dev/null
@@ -0,0 +1,16 @@
+int printf(const char* fmt, ...);
+
+typedef int (*add_pt)(int a, int b);
+
+int add(int a, int b)
+{
+       return a + b;
+}
+
+int main()
+{
+       add_pt f = add;
+
+       printf("typedef f: %p, f(1, 2): %d\n", f, f(1, 2));
+       return 0;
+}
index 8c90a389ae8a3a9b4a0fbef5e463b21647c7b35b..e4e41a840126d88295248f2b2254427ba7a2e883 100644 (file)
@@ -193,6 +193,8 @@ static int _x64_peephole_mov(scf_vector_t* save_insts, scf_vector_t* peep_insts,
 
                                if (x64_inst_data_is_reg(&inst->dst))
                                        __x64_peep_mov_by_lea(inst, std);
+
+                               std->nb_used++;
                                break;
 
                        } else if (scf_inst_data_same(&std->src, &inst->src))
index a3764d2be4aff49a8c1f0d4a09358aa3ff7f485a..f6cd515097beafa52856459ff6b42ef4ba08e475 100644 (file)
@@ -10,16 +10,10 @@ typedef struct {
 
        int              nb_lbs;
        int              nb_rbs;
-} dfa_class_data_t;
 
-static int _class_is_class(scf_dfa_t* dfa, void* word)
-{
-       scf_lex_word_t* w = word;
+       uint8_t          typedef_flag:1;
+} dfa_class_data_t;
 
-       return SCF_LEX_WORD_KEY_CLASS  == w->type
-               || SCF_LEX_WORD_KEY_STRUCT == w->type
-               || SCF_LEX_WORD_KEY_UNION  == w->type;
-}
 
 static int _class_action_lb(scf_dfa_t* dfa, scf_vector_t* words, void* data)
 {
@@ -33,6 +27,15 @@ static int _class_action_lb(scf_dfa_t* dfa, scf_vector_t* words, void* data)
        scf_stack_t*     s     = d->module_datas[dfa_module_class.index];
        scf_type_t*      t     = NULL;
 
+       while (d->current_identities->size > 0) {
+
+               dfa_identity_t* id = scf_stack_pop(d->current_identities);
+               if (id) {
+                       free(id);
+                       id = NULL;
+               }
+       }
+
        if (SCF_LEX_WORD_ID == key->type) {
                t = scf_block_find_type(ast->current_block, key->text->data);
 
@@ -42,6 +45,9 @@ static int _class_action_lb(scf_dfa_t* dfa, scf_vector_t* words, void* data)
                                return SCF_DFA_ERROR;
 
                        ast->nb_structs++;
+
+                       scf_scope_push_type(ast->current_block->scope, t);
+                       scf_node_add_child((scf_node_t*)ast->current_block, (scf_node_t*)t);
                }
 
                assert(words->size >= 3);
@@ -58,14 +64,15 @@ static int _class_action_lb(scf_dfa_t* dfa, scf_vector_t* words, void* data)
 
                ast->nb_structs++;
 
+               scf_scope_push_type(ast->current_block->scope, t);
+               scf_node_add_child((scf_node_t*)ast->current_block, (scf_node_t*)t);
+
                t->node.anon_flag = 1;
        }
 
        if (!t->scope)
                t->scope = scf_scope_alloc();
 
-       scf_scope_push_type(ast->current_block->scope, t);
-
        switch (key->type)
        {
                case SCF_LEX_WORD_KEY_STRUCT:
@@ -76,13 +83,13 @@ static int _class_action_lb(scf_dfa_t* dfa, scf_vector_t* words, void* data)
                case SCF_LEX_WORD_KEY_UNION:
                        t->node.union_flag = 1;
                        break;
+
                default:
+                       scf_loge("key word '%s' NOT support, file: %s, line: %d\n", key->text->data, key->file->data, key->line);
                        return SCF_DFA_ERROR;
                        break;
        };
 
-       scf_node_add_child((scf_node_t*)ast->current_block, (scf_node_t*)t);
-
        dfa_class_data_t* cd = calloc(1, sizeof(dfa_class_data_t));
        if (!cd)
                return -ENOMEM;
@@ -97,6 +104,9 @@ static int _class_action_lb(scf_dfa_t* dfa, scf_vector_t* words, void* data)
        cd->current_type = t;
        cd->nb_lbs++;
 
+       cd->typedef_flag = d->typedef_flag;
+       d ->typedef_flag = 0;
+
        ast->current_block = (scf_block_t*)t;
 
        SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "class_end"), SCF_DFA_HOOK_END);
@@ -367,6 +377,9 @@ static int _class_action_rb(scf_dfa_t* dfa, scf_vector_t* words, void* data)
 
                dfa->ops->push_word(dfa, w);
 
+               d ->typedef_flag = cd->typedef_flag;
+               cd->typedef_flag = 0;
+
        } else if (SCF_LEX_WORD_SEMICOLON == w->type
                        && s->size > 1
                        && cd->current_type->node.anon_flag) {
@@ -416,8 +429,63 @@ static int _class_action_var(scf_dfa_t* dfa, scf_vector_t* words, void* data)
        return SCF_DFA_NEXT_WORD;
 }
 
+int __class_add_type(scf_ast_t* ast, scf_lex_word_t* key, scf_lex_word_t* name)
+{
+       if (SCF_LEX_WORD_ID == name->type
+                       && (SCF_LEX_WORD_KEY_STRUCT   == key->type
+                               || SCF_LEX_WORD_KEY_UNION == key->type
+                               || SCF_LEX_WORD_KEY_CLASS == key->type)) {
+
+               scf_type_t* t = scf_block_find_type(ast->current_block, name->text->data);
+               if (t)
+                       return SCF_DFA_OK;
+
+               t = scf_type_alloc(name, name->text->data, SCF_STRUCT + ast->nb_structs, 0);
+               if (!t)
+                       return SCF_DFA_ERROR;
+
+               switch (key->type)
+               {
+                       case SCF_LEX_WORD_KEY_STRUCT:
+                       case SCF_LEX_WORD_KEY_CLASS:
+                               t->node.class_flag = 1;
+                               break;
+
+                       case SCF_LEX_WORD_KEY_UNION:
+                               t->node.union_flag = 1;
+                               break;
+                       default:
+                               scf_loge("key word '%s' NOT support, file: %s, line: %d\n", key->text->data, key->file->data, key->line);
+
+                               scf_type_free(t);
+                               t = NULL;
+                               return SCF_DFA_ERROR;
+                               break;
+               };
+
+               ast->nb_structs++;
+
+               scf_scope_push_type(ast->current_block->scope, t);
+               scf_node_add_child((scf_node_t*)ast->current_block, (scf_node_t*)t);
+       }
+
+       return SCF_DFA_OK;
+}
+
 static int _class_action_semicolon(scf_dfa_t* dfa, scf_vector_t* words, void* data)
 {
+       scf_parse_t*     parse = dfa->priv;
+       scf_ast_t*       ast   = parse->ast;
+       scf_lex_word_t*  name;
+       scf_lex_word_t*  key;
+
+       if (words->size >= 3) {
+               name = words->data[words->size - 2];
+               key  = words->data[words->size - 3];
+
+               return __class_add_type(ast, key, name);
+       }
+
        return SCF_DFA_OK;
 }
 
@@ -443,9 +511,6 @@ static int _class_action_end(scf_dfa_t* dfa, scf_vector_t* words, void* data)
 
 static int _dfa_init_module_class(scf_dfa_t* dfa)
 {
-       SCF_DFA_MODULE_NODE(dfa, class, _class,    _class_is_class,      NULL);
-
-       SCF_DFA_MODULE_NODE(dfa, class, identity,  scf_dfa_is_identity,  NULL);
        SCF_DFA_MODULE_NODE(dfa, class, lb,        scf_dfa_is_lb,        _class_action_lb);
        SCF_DFA_MODULE_NODE(dfa, class, rb,        scf_dfa_is_rb,        _class_action_rb);
        SCF_DFA_MODULE_NODE(dfa, class, semicolon, scf_dfa_is_semicolon, _class_action_semicolon);
@@ -486,8 +551,6 @@ static int _dfa_fini_module_class(scf_dfa_t* dfa)
 
 static int _dfa_init_syntax_class(scf_dfa_t* dfa)
 {
-       SCF_DFA_GET_MODULE_NODE(dfa, class,  _class,    _class);
-       SCF_DFA_GET_MODULE_NODE(dfa, class,  identity,  type_name);
        SCF_DFA_GET_MODULE_NODE(dfa, class,  lb,        lb);
        SCF_DFA_GET_MODULE_NODE(dfa, class,  rb,        rb);
        SCF_DFA_GET_MODULE_NODE(dfa, class,  end,       end);
@@ -497,16 +560,7 @@ static int _dfa_init_syntax_class(scf_dfa_t* dfa)
 
        SCF_DFA_GET_MODULE_NODE(dfa, type,   entry,     member);
 
-       scf_vector_add(dfa->syntaxes,     _class);
-
-       // class start
-       scf_dfa_node_add_child(_class,    type_name);
-
-       scf_dfa_node_add_child(type_name, semicolon);
-       scf_dfa_node_add_child(type_name, lb);
-
-       // anonymous class
-       scf_dfa_node_add_child(_class,    lb);
+       // class start define in scf_dfa_type.c
 
        // empty class
        scf_dfa_node_add_child(lb,        rb);
index 78f6d3804cab187b3f5dd96b87c2c2b2d229ea21..3213c091a54f5582bb862a42870bab53034eaac3 100644 (file)
@@ -93,7 +93,7 @@ int _expr_add_var(scf_parse_t* parse, dfa_data_t* d)
                return SCF_DFA_ERROR;
 
        if (!var) {
-               scf_logw("var '%s' not found, maybe it's a function\n", w->text->data);
+               scf_logw("var '%s' not found, it may be a function\n", w->text->data);
 
                if (scf_ast_find_type_type(&pt, parse->ast, SCF_FUNCTION_PTR) < 0)
                        return SCF_DFA_ERROR;
@@ -103,8 +103,8 @@ int _expr_add_var(scf_parse_t* parse, dfa_data_t* d)
                        return SCF_DFA_ERROR;
 
                if (!f) {
-                       scf_loge("function '%s' not found\n", w->text->data);
-                       return SCF_DFA_ERROR;
+                       scf_logw("function '%s' not found, it may be a struct\n", w->text->data);
+                       return SCF_DFA_NEXT_SYNTAX;
                }
 
                var = SCF_VAR_ALLOC_BY_TYPE(id->identity, pt, 1, 1, f);
@@ -154,14 +154,10 @@ static int _expr_action_expr(scf_dfa_t* dfa, scf_vector_t* words, void* data)
 
        if (!d->expr) {
                d->expr = scf_expr_alloc();
-               if (!d->expr) {
-                       scf_loge("expr alloc failed\n");
+               if (!d->expr)
                        return SCF_DFA_ERROR;
-               }
        }
 
-       scf_logd("d->expr: %p\n", d->expr);
-
        return words->size > 0 ? SCF_DFA_CONTINUE : SCF_DFA_NEXT_WORD;
 }
 
@@ -724,8 +720,11 @@ int _expr_fini_expr(scf_parse_t* parse, dfa_data_t* d, int semi_flag)
        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;
+
+               int ret = _expr_add_var(parse, d);
+
+               if (SCF_DFA_OK != ret)
+                       return ret;
        }
 
        if (md->parent_block) {
@@ -777,20 +776,23 @@ static int _expr_action_comma(scf_dfa_t* dfa, scf_vector_t* words, void* data)
        scf_parse_t*  parse = dfa->priv;
        dfa_data_t*   d     = data;
 
-       if (_expr_fini_expr(parse, d, 0) < 0)
-               return SCF_DFA_ERROR;
+       int ret = _expr_fini_expr(parse, d, 0);
+
+       if (SCF_DFA_OK != ret)
+               return ret;
 
        return SCF_DFA_NEXT_WORD;
 }
 
 static int _expr_action_semicolon(scf_dfa_t* dfa, scf_vector_t* words, void* data)
 {
-       scf_parse_t*         parse = dfa->priv;
-       dfa_data_t*          d     = data;
-       expr_module_data_t*  md    = d->module_datas[dfa_module_expr.index];
+       scf_parse_t*  parse = dfa->priv;
+       dfa_data_t*   d     = data;
 
-       if (_expr_fini_expr(parse, d, 1) < 0)
-               return SCF_DFA_ERROR;
+       int ret = _expr_fini_expr(parse, d, 1);
+
+       if (SCF_DFA_OK != ret)
+               return ret;
 
        return SCF_DFA_OK;
 }
index 40b293df627395f294fc93c0fb40483802bd6b8c..e6b472e34db81d508a20cfd5095c8d628ff388ab 100644 (file)
@@ -5,35 +5,43 @@
 extern scf_dfa_module_t dfa_module_function;
 
 typedef struct {
-
        scf_block_t*     parent_block;
 
-       int              pf_pointers;
+       scf_variable_t*  v_pf;
+
        int              pf_lps;
        int              pf_rps;
 } dfa_fun_data_t;
 
 int _function_add_function(scf_dfa_t* dfa, dfa_data_t* d)
 {
-       if (d->current_identities->size < 2) {
-               scf_loge("d->current_identities->size: %d\n", d->current_identities->size);
-               return SCF_DFA_ERROR;
-       }
-
        scf_parse_t*     parse = dfa->priv;
        scf_ast_t*       ast   = parse->ast;
-       dfa_identity_t*  id    = scf_stack_pop(d->current_identities);
+       dfa_identity_t*  id    = NULL;
        dfa_fun_data_t*  fd    = d->module_datas[dfa_module_function.index];
+       scf_lex_word_t*  name  = NULL;
 
+       dfa_identity_t*  id0;
        scf_variable_t*  v_pf = NULL;
        scf_function_t*  f;
        scf_variable_t*  v;
        scf_block_t*     b;
        scf_type_t*      t;
 
-       if (!id || !id->identity) {
-               scf_loge("function identity not found\n");
-               return SCF_DFA_ERROR;
+       if (d->current_var) {
+               name = scf_lex_word_clone(d->current_var->w);
+               if (!name)
+                       return -ENOMEM;
+
+       } else {
+               id = scf_stack_pop(d->current_identities);
+
+               if (!id || !id->identity) {
+                       scf_loge("function identity not found\n");
+                       return SCF_DFA_ERROR;
+               }
+
+               name = id->identity;
        }
 
        uint32_t local_flag  = 0;
@@ -65,41 +73,64 @@ int _function_add_function(scf_dfa_t* dfa, dfa_data_t* d)
 
        assert(global_flag || local_flag || member_flag);
 
-       if (fd->pf_pointers > 0) {
+       if (d->pf_pointers > 0) {
                t = NULL;
 
-               int pf_pointers = fd->pf_pointers;
+               int ret;
+               int pf_pointers = d->pf_pointers;
 
-               fd->pf_pointers = 0;
+               d->pf_pointers = 0;
 
-               int ret = scf_ast_find_type_type(&t, ast, SCF_FUNCTION_PTR);
-               if (ret < 0)
-                       return ret;
+               if (!d->current_var) {
+                       ret = scf_ast_find_type_type(&t, ast, SCF_FUNCTION_PTR);
+                       if (ret < 0)
+                               return ret;
 
-               v_pf = SCF_VAR_ALLOC_BY_TYPE(id->identity, t, 0, pf_pointers, NULL);
-               if (!v_pf)
-                       return -ENOMEM;
+                       v_pf = SCF_VAR_ALLOC_BY_TYPE(name, t, 0, pf_pointers, NULL);
+                       if (!v_pf)
+                               return -ENOMEM;
+
+                       v_pf->local_flag  = local_flag;
+                       v_pf->global_flag = global_flag;
+                       v_pf->member_flag = member_flag;
+               } else
+                       v_pf = d->current_var;
+
+               assert(d->current_identities->size > 0);
+               id0  = d->current_identities->data[0];
+
+               if (id0->typedef_flag) {
+                       id0->typedef_flag = 0;
 
-               scf_scope_push_var(ast->current_block->scope, v_pf);
+                       v_pf->typedef_flag = 1;
+
+                       ret = scf_vector_add(ast->current_block->scope->typedef_vars, v_pf);
+               } else
+                       ret = scf_scope_push_var(ast->current_block->scope, v_pf);
+
+               if (ret < 0) {
+                       scf_variable_free(v_pf);
+                       return ret;
+               }
 
-               ret = scf_string_cat_cstr(id->identity->text, "_pt");
+               ret = scf_string_cat_cstr(name->text, "__");
                if (ret < 0)
                        return ret;
 
-               v_pf->local_flag  = local_flag;
-               v_pf->global_flag = global_flag;
-               v_pf->member_flag = member_flag;
+               fd->v_pf = v_pf;
        }
 
-       f = scf_function_alloc(id->identity);
+       f = scf_function_alloc(name);
        if (!f)
                return SCF_DFA_ERROR;
        f->member_flag = member_flag;
 
-       free(id);
-       id = NULL;
+       if (id) {
+               free(id);
+               id = NULL;
+       }
 
-       scf_logi("function: %s,line:%d, member_flag: %d\n", f->node.w->text->data, f->node.w->line, f->member_flag);
+       scf_logi("function: %s(), line: %d, member_flag: %d\n", f->node.w->text->data, f->node.w->line, f->member_flag);
 
        int void_flag = 0;
 
@@ -300,7 +331,7 @@ static int _function_action_pf_star(scf_dfa_t* dfa, scf_vector_t* words, void* d
        dfa_data_t*      d     = data;
        dfa_fun_data_t*  fd    = d->module_datas[dfa_module_function.index];
 
-       fd->pf_pointers++;
+       d->pf_pointers++;
 
        return SCF_DFA_NEXT_WORD;
 }
@@ -330,7 +361,7 @@ static int _function_action_pf_rp(scf_dfa_t* dfa, scf_vector_t* words, void* dat
                fd->pf_lps = 0;
 
                if (id && id->identity)
-                       scf_logw("pf: %s(), nb_pointers: %d\n", id->identity->text->data, fd->pf_pointers);
+                       scf_logw("pf: %s(), nb_pointers: %d\n", id->identity->text->data, d->pf_pointers);
        } else {
                SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "function_pf_rp"), SCF_DFA_HOOK_PRE);
        }
@@ -346,11 +377,14 @@ static int _function_action_lp(scf_dfa_t* dfa, scf_vector_t* words, void* data)
 
        assert(!d->current_node);
 
-       d->current_var = NULL;
+       if (d->pf_pointers <= 0)
+               d->current_var = NULL;
 
        if (_function_add_function(dfa, d) < 0)
                return SCF_DFA_ERROR;
 
+       d->current_var = NULL;
+
        SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "function_rp"),    SCF_DFA_HOOK_PRE);
        SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "function_comma"), SCF_DFA_HOOK_PRE);
 
@@ -568,6 +602,10 @@ static int _dfa_init_syntax_function(scf_dfa_t* dfa)
        SCF_DFA_GET_MODULE_NODE(dfa, type,     identity,  identity);
        SCF_DFA_GET_MODULE_NODE(dfa, block,    entry,     block);
 
+       SCF_DFA_GET_MODULE_NODE(dfa, var,      ls,        ls);
+       SCF_DFA_GET_MODULE_NODE(dfa, var,      rs,        rs);
+       SCF_DFA_GET_MODULE_NODE(dfa, var,      assign,    assign);
+
        // function pointer
        scf_dfa_node_add_child(base_type, pf_lp);
        scf_dfa_node_add_child(type_name, pf_lp);
@@ -577,6 +615,10 @@ static int _dfa_init_syntax_function(scf_dfa_t* dfa)
        scf_dfa_node_add_child(pf_star,   identity);
        scf_dfa_node_add_child(identity,  pf_rp);
 
+       scf_dfa_node_add_child(identity,  ls);
+       scf_dfa_node_add_child(identity,  assign);
+       scf_dfa_node_add_child(rs,        pf_rp);
+
        scf_dfa_node_add_child(pf_star,   pf_star);
        scf_dfa_node_add_child(pf_lp,     pf_lp);
        scf_dfa_node_add_child(pf_rp,     pf_rp);
index d2752f31e787164e736d9bad6995005e25198f81..fca7f19b13f8e25f2adaca583494c03a7a8d318b 100644 (file)
@@ -4,6 +4,8 @@
 
 extern scf_dfa_module_t dfa_module_type;
 
+int __class_add_type(scf_ast_t* ast, scf_lex_word_t* key, scf_lex_word_t* name);
+
 static int _type_is__struct(scf_dfa_t* dfa, void* word)
 {
        scf_lex_word_t* w = word;
@@ -13,6 +15,15 @@ static int _type_is__struct(scf_dfa_t* dfa, void* word)
                || SCF_LEX_WORD_KEY_UNION  == w->type;
 }
 
+static int _type_action_typedef(scf_dfa_t* dfa, scf_vector_t* words, void* data)
+{
+       dfa_data_t* d = data;
+
+       d->typedef_flag = 1;
+
+       return SCF_DFA_NEXT_WORD;
+}
+
 static int _type_action_const(scf_dfa_t* dfa, scf_vector_t* words, void* data)
 {
        dfa_data_t* d = data;
@@ -73,17 +84,19 @@ static int _type_action_base_type(scf_dfa_t* dfa, scf_vector_t* words, void* dat
                return SCF_DFA_ERROR;
        }
 
-       id->type_w      = w;
+       id->type_w       = w;
 
-       id->const_flag  = d->const_flag;
-       id->static_flag = d->static_flag;
-       id->extern_flag = d->extern_flag;
-       id->inline_flag = d->inline_flag;
+       id->const_flag   = d->const_flag;
+       id->static_flag  = d->static_flag;
+       id->extern_flag  = d->extern_flag;
+       id->inline_flag  = d->inline_flag;
+       id->typedef_flag = d->typedef_flag;
 
-       d ->const_flag  = 0;
-       d ->static_flag = 0;
-       d ->extern_flag = 0;
-       d ->inline_flag = 0;
+       d->const_flag    = 0;
+       d->static_flag   = 0;
+       d->extern_flag   = 0;
+       d->inline_flag   = 0;
+       d->typedef_flag  = 0;
 
        return SCF_DFA_NEXT_WORD;
 }
@@ -115,16 +128,28 @@ int _type_find_type(scf_dfa_t* dfa, dfa_identity_t* id)
        if (!id->identity)
                return 0;
 
-       id->type = scf_block_find_type(parse->ast->current_block, id->identity->text->data);
-       if (!id->type) {
+       int ret = scf_ast_find_type(&id->type, parse->ast, id->identity->text->data);
+       if (ret < 0)
+               return SCF_DFA_ERROR;
 
-               int ret = scf_ast_find_global_type(&id->type, parse->ast, id->identity->text->data);
-               if (ret < 0) {
-                       scf_loge("find global function error\n");
+       if (!id->type) {
+               ret = scf_ast_find_typedef(&id->type_def, parse->ast, id->identity->text->data);
+               if (ret < 0)
                        return SCF_DFA_ERROR;
-               }
 
-               if (!id->type) {
+               if (id->type_def) {
+                       scf_logw("find typedef '%s'\n", id->identity->text->data);
+
+                       ret = scf_ast_find_type_type(&id->type, parse->ast, id->type_def->type);
+                       if (ret < 0)
+                               return SCF_DFA_ERROR;
+
+                       id->func_ptr = id->type_def->func_ptr;
+
+                       assert(id->type);
+               } else {
+                       scf_logw("can't find type '%s', it may be an function ptr\n", id->identity->text->data);
+
                        id->type = scf_block_find_type_type(parse->ast->current_block, SCF_FUNCTION_PTR);
 
                        if (!id->type) {
@@ -133,7 +158,7 @@ int _type_find_type(scf_dfa_t* dfa, dfa_identity_t* id)
                        }
                }
 
-               if (SCF_FUNCTION_PTR == id->type->node.type) {
+               if (SCF_FUNCTION_PTR == id->type->node.type && !id->type_def) {
 
                        id->func_ptr = _type_find_function(parse->ast->current_block, id->identity->text->data);
 
@@ -155,19 +180,47 @@ static int _type_action_identity(scf_dfa_t* dfa, scf_vector_t* words, void* data
        scf_lex_word_t*  w     = words->data[words->size - 1];
        dfa_data_t*      d     = data;
        scf_stack_t*     s     = d->current_identities;
+       dfa_identity_t*  type  = NULL;
        dfa_identity_t*  id    = NULL;
+       int ret;
 
        if (s->size > 0) {
-               id = scf_stack_top(s);
+               type = scf_stack_top(s);
 
-               int ret = _type_find_type(dfa, id);
+               if (d->typedef_flag) {
+
+                       if (words->size < 3) {
+                               scf_loge("\n");
+                               return SCF_DFA_ERROR;
+                       }
+
+                       scf_lex_word_t*  name = words->data[words->size - 2];
+                       scf_lex_word_t*  key  = words->data[words->size - 3];
+
+                       if (SCF_LEX_WORD_KEY_STRUCT   == key->type
+                                       || SCF_LEX_WORD_KEY_UNION == key->type
+                                       || SCF_LEX_WORD_KEY_CLASS == key->type) {
+
+                               ret = __class_add_type(parse->ast, key, name);
+                               if (ret < 0)
+                                       return ret;
+                       }
+               }
+
+               ret = _type_find_type(dfa, type);
                if (ret < 0) {
                        scf_loge("\n");
                        return ret;
                }
+
+               if (d->typedef_flag) {
+                       type->typedef_flag = d->typedef_flag;
+
+                       d->typedef_flag = 0;
+               }
        }
 
-       id  = calloc(1, sizeof(dfa_identity_t));
+       id = calloc(1, sizeof(dfa_identity_t));
        if (!id)
                return SCF_DFA_ERROR;
 
@@ -175,6 +228,7 @@ static int _type_action_identity(scf_dfa_t* dfa, scf_vector_t* words, void* data
                free(id);
                return SCF_DFA_ERROR;
        }
+
        id->identity = w;
 
        return SCF_DFA_NEXT_WORD;
@@ -224,6 +278,7 @@ static int _dfa_init_module_type(scf_dfa_t* dfa)
 
        SCF_DFA_MODULE_NODE(dfa, type, _struct,   _type_is__struct,     NULL);
 
+       SCF_DFA_MODULE_NODE(dfa, type, _typedef,  scf_dfa_is_typedef,   _type_action_typedef);
        SCF_DFA_MODULE_NODE(dfa, type, _const,    scf_dfa_is_const,     _type_action_const);
        SCF_DFA_MODULE_NODE(dfa, type, _static,   scf_dfa_is_static,    _type_action_static);
        SCF_DFA_MODULE_NODE(dfa, type, _extern,   scf_dfa_is_extern,    _type_action_extern);
@@ -241,6 +296,7 @@ static int _dfa_init_syntax_type(scf_dfa_t* dfa)
 {
        SCF_DFA_GET_MODULE_NODE(dfa, type,     entry,     entry);
 
+       SCF_DFA_GET_MODULE_NODE(dfa, type,     _typedef,  _typedef);
        SCF_DFA_GET_MODULE_NODE(dfa, type,     _const,    _const);
        SCF_DFA_GET_MODULE_NODE(dfa, type,     _static,   _static);
        SCF_DFA_GET_MODULE_NODE(dfa, type,     _extern,   _extern);
@@ -254,9 +310,13 @@ static int _dfa_init_syntax_type(scf_dfa_t* dfa)
 
        SCF_DFA_GET_MODULE_NODE(dfa, identity, identity,  type_name);
 
+       SCF_DFA_GET_MODULE_NODE(dfa, class,    lb,        class_lb);
+       SCF_DFA_GET_MODULE_NODE(dfa, class,    semicolon, class_semicolon);
+
 
        scf_vector_add(dfa->syntaxes,     entry);
 
+       scf_dfa_node_add_child(entry,     _typedef);
        scf_dfa_node_add_child(entry,     _static);
        scf_dfa_node_add_child(entry,     _extern);
        scf_dfa_node_add_child(entry,     _const);
@@ -266,6 +326,11 @@ static int _dfa_init_syntax_type(scf_dfa_t* dfa)
        scf_dfa_node_add_child(entry,     base_type);
        scf_dfa_node_add_child(entry,     type_name);
 
+       scf_dfa_node_add_child(_typedef,  _const);
+       scf_dfa_node_add_child(_typedef,  _struct);
+       scf_dfa_node_add_child(_typedef,  base_type);
+       scf_dfa_node_add_child(_typedef,  type_name);
+
        scf_dfa_node_add_child(_static,   _struct);
        scf_dfa_node_add_child(_static,   base_type);
        scf_dfa_node_add_child(_static,   type_name);
@@ -287,7 +352,11 @@ static int _dfa_init_syntax_type(scf_dfa_t* dfa)
        scf_dfa_node_add_child(_extern,   _const);
        scf_dfa_node_add_child(_inline,   _const);
 
+       // struct / union / class
        scf_dfa_node_add_child(_struct,   type_name);
+       scf_dfa_node_add_child(type_name, class_semicolon); // only declare
+       scf_dfa_node_add_child(type_name, class_lb); // define
+       scf_dfa_node_add_child(_struct,   class_lb); // define anonymous
 
        // multi-pointer
        scf_dfa_node_add_child(star,      star);
index c626f5615548bb9b9057b2ecf7bbbda0ea153cbb..63f5008edc22268dacd4e319e1667ebcc789f9ac 100644 (file)
@@ -43,11 +43,15 @@ int _check_recursive(scf_type_t* parent, scf_type_t* child, scf_lex_word_t* w)
 static int _var_add_var(scf_dfa_t* dfa, dfa_data_t* d)
 {
        scf_parse_t*     parse = dfa->priv;
+       scf_ast_t*       ast   = parse->ast;
        dfa_identity_t*  id    = scf_stack_top(d->current_identities);
+       dfa_identity_t*  id0   = NULL;
+       scf_variable_t*  v     = NULL;
+       scf_type_t*      t     = NULL;
 
        if (id && id->identity) {
 
-               scf_variable_t* v = scf_scope_find_variable(parse->ast->current_block->scope, id->identity->text->data);
+               v = scf_scope_find_variable(ast->current_block->scope, id->identity->text->data);
                if (v) {
                        scf_loge("repeated declare var '%s', line: %d\n", id->identity->text->data, id->identity->line);
                        return SCF_DFA_ERROR;
@@ -55,10 +59,41 @@ static int _var_add_var(scf_dfa_t* dfa, dfa_data_t* d)
 
                assert(d->current_identities->size >= 2);
 
-               dfa_identity_t* id0 = d->current_identities->data[0];
+               id0 = d->current_identities->data[0];
+
                assert(id0 && id0->type);
 
-               scf_block_t* b = parse->ast->current_block;
+               t = id0->type;
+
+               int   const_flag  = id0->const_flag;
+               int   nb_pointers = id0->nb_pointers;
+               void* func_ptr    = id0->func_ptr;
+
+               if (id0->type_def) {
+                       const_flag  |= id0->type_def->const_flag;
+                       nb_pointers += id0->type_def->nb_pointers;
+
+                       if (!func_ptr)
+                               func_ptr = id0->type_def->func_ptr;
+               }
+
+               if (d->pf_pointers > 0) {
+                       nb_pointers = d->pf_pointers;
+
+                       t = scf_block_find_type_type(ast->current_block, SCF_FUNCTION_PTR);
+               }
+
+               if (SCF_VAR_VOID == t->node.type && 0 == nb_pointers) {
+                       scf_loge("void var must be a pointer, like 'void*'\n");
+                       return SCF_DFA_ERROR;
+               }
+
+               if (SCF_FUNCTION_PTR == t->node.type && 0 == nb_pointers) {
+                       scf_loge("invalid func ptr\n");
+                       return SCF_DFA_ERROR;
+               }
+
+               scf_block_t* b = ast->current_block;
                while (b) {
                        if (b->node.type >= SCF_STRUCT || SCF_FUNCTION == b->node.type)
                                break;
@@ -84,10 +119,10 @@ static int _var_add_var(scf_dfa_t* dfa, dfa_data_t* d)
                        global_flag = 0;
                        member_flag = 1;
 
-                       if (0 == id0->nb_pointers && id0->type->node.type >= SCF_STRUCT) {
+                       if (0 == nb_pointers && t->node.type >= SCF_STRUCT) {
                                // if not pointer var, check if define recursive struct/union/class var
 
-                               if (_check_recursive((scf_type_t*)b, id0->type, id->identity) < 0) {
+                               if (_check_recursive((scf_type_t*)b, t, id->identity) < 0) {
 
                                        scf_loge("recursive define when define var '%s', line: %d\n",
                                                        id->identity->text->data, id->identity->line);
@@ -96,56 +131,59 @@ static int _var_add_var(scf_dfa_t* dfa, dfa_data_t* d)
                        }
                }
 
-               if (SCF_FUNCTION_PTR == id0->type->node.type
-                               && (!id0->func_ptr || 0 == id0->nb_pointers)) {
-                       scf_loge("invalid func ptr\n");
-                       return SCF_DFA_ERROR;
-               }
-
                if (id0->extern_flag) {
                        if (!global_flag) {
                                scf_loge("extern var must be global.\n");
                                return SCF_DFA_ERROR;
                        }
 
-                       scf_variable_t* v = scf_block_find_variable(parse->ast->current_block, id->identity->text->data);
+                       v = scf_block_find_variable(ast->current_block, id->identity->text->data);
                        if (v) {
                                scf_loge("extern var already declared, line: %d\n", v->w->line);
                                return SCF_DFA_ERROR;
                        }
                }
 
-               if (SCF_VAR_VOID == id0->type->node.type && 0 == id0->nb_pointers) {
-                       scf_loge("void var must be a pointer, like void*\n");
-                       return SCF_DFA_ERROR;
-               }
-
-               v = SCF_VAR_ALLOC_BY_TYPE(id->identity, id0->type, id0->const_flag, id0->nb_pointers, id0->func_ptr);
+               v = SCF_VAR_ALLOC_BY_TYPE(id->identity, t, const_flag, nb_pointers, func_ptr);
                if (!v) {
                        scf_loge("alloc var failed\n");
                        return SCF_DFA_ERROR;
                }
-               v->local_flag  = local_flag;
-               v->global_flag = global_flag;
-               v->member_flag = member_flag;
+               v->local_flag   = local_flag;
+               v->global_flag  = global_flag;
+               v->member_flag  = member_flag;
+
+               v->static_flag  = id0->static_flag;
+               v->extern_flag  = id0->extern_flag;
+               v->typedef_flag = id0->typedef_flag;
+
+               if (id0->type_def) {
+                       int i;
+                       scf_dimention_t* dim;
 
-               v->static_flag = id0->static_flag;
-               v->extern_flag = id0->extern_flag;
+                       for (i  = 0; i < id0->type_def->nb_dimentions; i++) {
+                               dim =       &id0->type_def->dimentions[i];
 
-               scf_logi("type: %d, nb_pointers: %d,nb_dimentions: %d, var: %s,line:%d,pos:%d, local: %d, global: %d, member: %d, extern: %d, static: %d\n\n",
-                               v->type, v->nb_pointers, v->nb_dimentions,
+                               scf_variable_add_array_dimention(v, dim->num, NULL);
+                       }
+
+                       v->const_literal_flag = id0->type_def->nb_dimentions > 0;
+               }
+
+               scf_logi("typedef_flag: %u, type: %d, nb_pointers: %d, nb_dimentions: %d, var: %s, line:%d, pos:%d, local: %d, global: %d, member: %d, extern: %d, static: %d\n\n",
+                               v->typedef_flag, v->type, v->nb_pointers, v->nb_dimentions,
                                v->w->text->data, v->w->line, v->w->pos,
                                v->local_flag,  v->global_flag, v->member_flag,
                                v->extern_flag, v->static_flag);
 
-               scf_scope_push_var(parse->ast->current_block->scope, v);
+               scf_scope_push_var(ast->current_block->scope, v);
 
-               d->current_var   = v;
-               d->current_var_w = id->identity;
-               id0->nb_pointers = 0;
-               id0->const_flag  = 0;
-               id0->static_flag = 0;
-               id0->extern_flag = 0;
+               d->current_var    = v;
+               d->current_var_w  = id->identity;
+               id0->nb_pointers  = 0;
+               id0->const_flag   = 0;
+               id0->static_flag  = 0;
+               id0->extern_flag  = 0;
 
                scf_stack_pop(d->current_identities);
                free(id);
@@ -443,6 +481,49 @@ static int _var_add_vla(scf_ast_t* ast, scf_variable_t* vla)
        return 0;
 }
 
+static int _var_add_typedef(scf_ast_t* ast, dfa_data_t* d)
+{
+       scf_variable_t*  v;
+
+       if (d->expr) {
+               scf_expr_free(d->expr);
+               d->expr = NULL;
+       }
+
+       if (d->expr_local_flag > 0)
+               d->expr_local_flag--;
+
+       if (d->current_var) {
+               v = scf_block_find_typedef(ast->current_block, d->current_var->w->text->data);
+               if (v) {
+                       scf_loge("repeated typedef '%s', 1st in file: %s, line: %d, 2nd in file: %s, line: %d\n",
+                                       v->w->text->data, v->w->file->data, v->w->line,
+                                       d->current_var->w->file->data,
+                                       d->current_var->w->line);
+                       return SCF_DFA_REPEATED;
+               }
+
+               v = d->current_var;
+
+               scf_logi("typedef_flag: %u, type: %d, nb_pointers: %d, nb_dimentions: %d, var: %s, line:%d, pos:%d, local: %d, global: %d, member: %d, extern: %d, static: %d\n\n",
+                               v->typedef_flag, v->type, v->nb_pointers, v->nb_dimentions,
+                               v->w->text->data, v->w->line, v->w->pos,
+                               v->local_flag,  v->global_flag, v->member_flag,
+                               v->extern_flag, v->static_flag);
+
+               int ret = scf_vector_add(ast->current_block->scope->typedef_vars, d->current_var);
+               if (ret < 0)
+                       return ret;
+
+               assert(0 == scf_vector_del(ast->current_block->scope->vars, d->current_var));
+
+               d->current_var->vla_flag = 0;
+               d->current_var = NULL;
+       }
+
+       return 0;
+}
+
 static int _var_action_comma(scf_dfa_t* dfa, scf_vector_t* words, void* data)
 {
        scf_parse_t*  parse = dfa->priv;
@@ -459,6 +540,15 @@ static int _var_action_comma(scf_dfa_t* dfa, scf_vector_t* words, void* data)
        if (d->current_var) {
                scf_variable_size(d->current_var);
 
+               if (d->current_var->typedef_flag) {
+
+                       int ret = _var_add_typedef(parse->ast, d);
+                       if (ret < 0)
+                               return ret;
+
+                       return SCF_DFA_SWITCH_TO;
+               }
+
                if (d->current_var->vla_flag) {
 
                        if (_var_add_vla(parse->ast, d->current_var) < 0)
@@ -496,6 +586,15 @@ static int _var_action_semicolon(scf_dfa_t* dfa, scf_vector_t* words, void* data
        if (d->current_var) {
                scf_variable_size(d->current_var);
 
+               if (d->current_var->typedef_flag) {
+
+                       int ret = _var_add_typedef(parse->ast, d);
+                       if (ret < 0)
+                               return ret;
+
+                       return SCF_DFA_OK;
+               }
+
                if (d->current_var->vla_flag) {
 
                        if (_var_add_vla(parse->ast, d->current_var) < 0)
@@ -523,8 +622,9 @@ static int _var_action_semicolon(scf_dfa_t* dfa, scf_vector_t* words, void* data
 
 static int _var_action_assign(scf_dfa_t* dfa, scf_vector_t* words, void* data)
 {
-       scf_parse_t*  parse = dfa->priv;
-       dfa_data_t*   d     = data;
+       scf_parse_t*     parse = dfa->priv;
+       dfa_data_t*      d     = data;
+       scf_lex_word_t*  w     = words->data[words->size - 1];
 
        if (_var_add_var(dfa, d) < 0) {
                scf_loge("add var error\n");
@@ -534,16 +634,18 @@ static int _var_action_assign(scf_dfa_t* dfa, scf_vector_t* words, void* data)
        d->nb_lss = 0;
        d->nb_rss = 0;
 
-       scf_lex_word_t*  w = words->data[words->size - 1];
-
        if (!d->current_var) {
                scf_loge("\n");
                return SCF_DFA_ERROR;
        }
 
+       if (d->current_var->typedef_flag) {
+               scf_loge("typedef can't be assigned by '%s', file: %s, line: %d\n", w->text->data, w->file->data, w->line);
+               return SCF_DFA_ERROR;
+       }
+
        if (d->current_var->extern_flag) {
-               scf_loge("extern var '%s' can't be inited here, line: %d\n",
-                               d->current_var->w->text->data, w->line);
+               scf_loge("extern var '%s' can't be inited here, line: %d\n", d->current_var->w->text->data, w->line);
                return SCF_DFA_ERROR;
        }
 
@@ -554,8 +656,7 @@ static int _var_action_assign(scf_dfa_t* dfa, scf_vector_t* words, void* data)
        }
 
        if (d->current_var->nb_dimentions > 0) {
-               scf_logi("var array '%s' init, nb_dimentions: %d\n",
-                               d->current_var->w->text->data, d->current_var->nb_dimentions);
+               scf_logi("var array '%s' init, nb_dimentions: %d\n", d->current_var->w->text->data, d->current_var->nb_dimentions);
                return SCF_DFA_NEXT_WORD;
        }
 
@@ -641,7 +742,11 @@ static int _var_action_ls(scf_dfa_t* dfa, scf_vector_t* words, void* data)
                return SCF_DFA_ERROR;
        }
 
-       assert(!d->expr);
+       if (d->expr) {
+               scf_expr_free(d->expr);
+               d->expr = NULL;
+       }
+
        scf_variable_add_array_dimention(d->current_var, -1, NULL);
        d->current_var->const_literal_flag = 1;
 
@@ -663,56 +768,61 @@ static int _var_action_rs(scf_dfa_t* dfa, scf_vector_t* words, void* data)
 
        scf_logd("d->expr: %p\n", d->expr);
 
-       if (d->expr) {
-               while(d->expr->parent)
-                       d->expr = d->expr->parent;
+       if (!d->expr)
+               return SCF_DFA_SWITCH_TO;
 
-               if (scf_expr_calculate(parse->ast, d->expr, &r) < 0) {
-                       scf_loge("scf_expr_calculate\n");
+       while(d->expr->parent)
+               d->expr = d->expr->parent;
 
-                       scf_expr_free(d->expr);
-                       d->expr = NULL;
-                       return SCF_DFA_ERROR;
-               }
+       if (scf_expr_calculate(parse->ast, d->expr, &r) < 0)
+               goto error;
 
-               assert(d->current_var->dim_index < d->current_var->nb_dimentions);
+       assert(d->current_var->dim_index < d->current_var->nb_dimentions);
 
-               if (!scf_variable_const(r) && SCF_OP_ASSIGN != d->expr->nodes[0]->type) {
+       if (!scf_variable_const(r) && SCF_OP_ASSIGN != d->expr->nodes[0]->type) {
 
-                       if (!d->current_var->local_flag) {
-                               scf_loge("variable length array '%s' must in local scope, file: %s, line: %d\n",
-                                               d->current_var->w->text->data, w->file->data, w->line);
+               if (d->current_var->typedef_flag) {
+                       scf_loge("variable length array '%s' can't be type defined, file: %s, line: %d\n",
+                                       d->current_var->w->text->data, w->file->data, w->line);
+                       goto error;
+               }
 
-                               scf_variable_free(r);
-                               r = NULL;
+               if (!d->current_var->local_flag) {
+                       scf_loge("variable length array '%s' must in local scope, file: %s, line: %d\n",
+                                       d->current_var->w->text->data, w->file->data, w->line);
+                       goto error;
+               }
 
-                               scf_expr_free(d->expr);
-                               d->expr = NULL;
-                               return SCF_DFA_ERROR;
-                       }
+               scf_logw("define variable length array, file: %s, line: %d\n", w->file->data, w->line);
 
-                       scf_logw("define variable length array, file: %s, line: %d\n", w->file->data, w->line);
+               d->current_var->dimentions[d->current_var->dim_index].vla = d->expr;
+               d->current_var->vla_flag = 1;
+               d->expr = NULL;
+       } else {
+               d->current_var->dimentions[d->current_var->dim_index].num = r->data.i;
 
-                       d->current_var->dimentions[d->current_var->dim_index].vla = d->expr;
-                       d->current_var->vla_flag = 1;
-                       d->expr = NULL;
-               } else {
-                       d->current_var->dimentions[d->current_var->dim_index].num = r->data.i;
+               scf_logi("dimentions: %d, size: %d\n",
+                               d->current_var->dim_index, d->current_var->dimentions[d->current_var->dim_index].num);
 
-                       scf_logi("dimentions: %d, size: %d\n",
-                                       d->current_var->dim_index, d->current_var->dimentions[d->current_var->dim_index].num);
+               scf_expr_free(d->expr);
+               d->expr = NULL;
+       }
 
-                       scf_expr_free(d->expr);
-                       d->expr = NULL;
-               }
+       d->current_var->dim_index++;
 
-               d->current_var->dim_index++;
+       scf_variable_free(r);
+       r = NULL;
+       return SCF_DFA_SWITCH_TO;
 
+error:
+       if (r) {
                scf_variable_free(r);
                r = NULL;
        }
 
-       return SCF_DFA_SWITCH_TO;
+       scf_expr_free(d->expr);
+       d->expr = NULL;
+       return SCF_DFA_ERROR;
 }
 
 static int _dfa_init_module_var(scf_dfa_t* dfa)
index 00b910fb1e5f1c0d20bfddd174dfe976a4b35624..69cc4efb83125bc2e82016dce91710ea52ceb630 100644 (file)
@@ -296,7 +296,8 @@ static int __debug_add_type(scf_dwarf_info_entry_t** pie, scf_dwarf_abbrev_decla
                        }
 
                        d = parse->debug->abbrevs->data[parse->debug->abbrevs->size - 1];
-                       d->has_children = t->scope->vars->size > 0;
+
+                       d->has_children = t->scope && t->scope->vars->size > 0;
                }
 
                types = parse->debug->struct_types;
@@ -524,10 +525,12 @@ static int _debug_add_type(scf_dwarf_info_entry_t** pie, scf_parse_t* parse, scf
 
 static int _debug_add_struct_type(scf_dwarf_info_entry_t** pie, scf_dwarf_abbrev_declaration_t** pad, scf_parse_t* parse, scf_type_t* t)
 {
-//     scf_dwarf_abbrev_declaration_t* d;
-       scf_dwarf_abbrev_attribute_t*   attr;
-       scf_dwarf_info_entry_t*         ie;
-       scf_dwarf_info_attr_t*          iattr;
+       scf_dwarf_abbrev_attribute_t*  attr;
+       scf_dwarf_info_entry_t*        ie;
+       scf_dwarf_info_attr_t*         iattr;
+       scf_dwarf_info_entry_t*        ie_member;
+       scf_variable_t*                v_member;
+       scf_type_t*                    t_member;
 
        int ret;
        int i;
@@ -538,40 +541,40 @@ static int _debug_add_struct_type(scf_dwarf_info_entry_t** pie, scf_dwarf_abbrev
 
        int nb_pointers = 0;
 
-       for (i = 0; i < t->scope->vars->size; i++) {
+       if (t->scope) {
+               for (i = 0; i < t->scope->vars->size; i++) {
+                       v_member  = t->scope->vars->data[i];
+                       t_member  = NULL;
 
-               scf_dwarf_info_entry_t* ie_member;
-               scf_variable_t*         v_member;
-               scf_type_t*             t_member;
+                       ret = scf_ast_find_type_type(&t_member, parse->ast, v_member->type);
+                       if (ret < 0)
+                               return ret;
 
-               v_member  = t->scope->vars->data[i];
-               ret = scf_ast_find_type_type(&t_member, parse->ast, v_member->type);
-               if (ret < 0)
-                       return ret;
+                       ie_member = _debug_find_type(parse, t_member, v_member->nb_pointers);
+                       if (!ie_member) {
 
-               ie_member = _debug_find_type(parse, t_member, v_member->nb_pointers);
-               if (!ie_member) {
+                               if (t_member != t) {
+                                       ret = _debug_add_type(&ie_member, parse, t_member, v_member->nb_pointers);
+                                       if (ret < 0) {
+                                               scf_loge("\n");
+                                               return ret;
+                                       }
+                               } else {
+                                       assert(v_member->nb_pointers > 0);
 
-                       if (t_member != t) {
-                               ret = _debug_add_type(&ie_member, parse, t_member, v_member->nb_pointers);
-                               if (ret < 0) {
-                                       scf_loge("\n");
-                                       return ret;
+                                       if (nb_pointers < v_member->nb_pointers)
+                                               nb_pointers = v_member->nb_pointers;
                                }
-                       } else {
-                               assert(v_member->nb_pointers > 0);
-
-                               if (nb_pointers < v_member->nb_pointers)
-                                       nb_pointers = v_member->nb_pointers;
                        }
+
+                       if (scf_vector_add(ie_member_types, ie_member) < 0)
+                               return -ENOMEM;
                }
 
-               if (scf_vector_add(ie_member_types, ie_member) < 0)
-                       return -ENOMEM;
+               assert(ie_member_types->size == t->scope->vars->size);
        }
 
-       assert(ie_member_types->size == t->scope->vars->size);
-
+       ie  = NULL;
        ret = __debug_add_type(&ie, pad, parse, t, 0, NULL);
        if (ret < 0) {
                scf_loge("\n");
@@ -586,22 +589,20 @@ static int _debug_add_struct_type(scf_dwarf_info_entry_t** pie, scf_dwarf_abbrev
                        return -ENOMEM;
        }
 
-       for (i = 0; i < t->scope->vars->size; i++) {
-
-               scf_dwarf_info_entry_t* ie_member;
-               scf_variable_t*         v_member;
-
-               v_member  = t->scope->vars->data[i];
+       if (t->scope) {
+               for (i = 0; i < t->scope->vars->size; i++) {
+                       v_member  = t->scope->vars->data[i];
+                       ie_member = NULL;
 
-               ret = __debug_add_member_var(&ie_member, parse, v_member, ie_member_types->data[i]);
-               if (ret < 0) {
-                       scf_loge("\n");
-                       return ret;
-               }
+                       ret = __debug_add_member_var(&ie_member, parse, v_member, ie_member_types->data[i]);
+                       if (ret < 0) {
+                               scf_loge("\n");
+                               return ret;
+                       }
 
-               if (nb_pointers > 0) {
-                       if (scf_vector_add(refills, ie_member) < 0) {
-                               return -ENOMEM;
+                       if (nb_pointers > 0) {
+                               if (scf_vector_add(refills, ie_member) < 0)
+                                       return -ENOMEM;
                        }
                }
        }
@@ -626,17 +627,18 @@ static int _debug_add_struct_type(scf_dwarf_info_entry_t** pie, scf_dwarf_abbrev
                int j;
                for (j = 1; j <= nb_pointers; j++) {
 
+                       ie_pointer = NULL;
+
                        ret = _debug_add_type(&ie_pointer, parse, t, j);
                        if (ret < 0) {
                                scf_loge("\n");
                                return ret;
                        }
 
-                       for (i = 0; i < t->scope->vars->size; i++) {
-
-                               scf_dwarf_info_entry_t* ie_member;
-                               scf_variable_t*         v_member;
+                       if (!t->scope)
+                               continue;
 
+                       for (i = 0; i < t->scope->vars->size; i++) {
                                v_member  = t->scope->vars->data[i];
 
                                if (v_member->type != t->node.type)
index 051ff1cc755cef180007d72b8bdccc0e4fc595c9..719e89c10e20c93e8fdbba12e464fbfb0d389d63 100644 (file)
@@ -50,15 +50,17 @@ typedef struct {
        scf_lex_word_t*      identity;
        scf_lex_word_t*      type_w;
        scf_type_t*          type;
+       scf_variable_t*      type_def;
 
        int                  number;
        int                  nb_pointers;
        scf_function_t*      func_ptr;
 
-       uint32_t             const_flag :1;
-       uint32_t             extern_flag:1;
-       uint32_t             static_flag:1;
-       uint32_t             inline_flag:1;
+       uint32_t             const_flag  :1;
+       uint32_t             extern_flag :1;
+       uint32_t             static_flag :1;
+       uint32_t             inline_flag :1;
+       uint32_t             typedef_flag:1;
 
 } dfa_identity_t;
 
@@ -77,6 +79,7 @@ struct dfa_data_s {
 
        scf_function_t*      current_function;
        int                  argc;
+       int                  pf_pointers;
 
        scf_lex_word_t*      current_async_w;