1, support 'va_copy()', 'offsetof()',
authoryu.dongliang <18588496441@163.com>
Sun, 16 Aug 2026 13:13:30 +0000 (21:13 +0800)
committeryu.dongliang <18588496441@163.com>
Sun, 16 Aug 2026 13:13:53 +0000 (21:13 +0800)
2, support <stdlib.h>, <string.h>, <stddef.h>, <stdarg.h> of musl libc.

24 files changed:
core/scf_3ac.c
core/scf_ast.c
core/scf_ast.h
core/scf_operator.c
core/scf_operator_handler_3ac.c
examples/hello.c
examples/offsetof.c [new file with mode: 0644]
examples/scf_printf.c
native/x64/scf_x64_inst.c
native/x64/scf_x64_rcg.c
parse/scf_dfa_expr.c
parse/scf_dfa_function.c
parse/scf_dfa_identity.c
parse/scf_dfa_type.c
parse/scf_dfa_va_arg.c
parse/scf_dfa_var.c
parse/scf_operator_handler_const.c
parse/scf_operator_handler_semantic.c
parse/scf_parse.c
parse/scf_parse.h
sysroot/include/stddef.h [new file with mode: 0644]
sysroot/include/stdlib.h [new file with mode: 0644]
sysroot/include/string.h [new file with mode: 0644]
sysroot/lib/__builtin__.h

index 5560a1905898e305680a6ca4d798992ed98cb25d..2b6d7dce4dc62b011c859f5eecab30426a4e296d 100644 (file)
@@ -57,6 +57,7 @@ static scf_3ac_operator_t _3ac_operators[] = {
        {SCF_OP_OR_ASSIGN,      "|="},
 
        {SCF_OP_VA_START,       "va_start"},
+       {SCF_OP_VA_COPY,        "va_copy"},
        {SCF_OP_VA_ARG,         "va_arg"},
        {SCF_OP_VA_END,         "va_end"},
 
index bad662e76df3fa574132a5fb5f3ccf4459a6563c..2bf5a93a52e8b80a3c5b6837782ab1c98536e325 100644 (file)
@@ -572,11 +572,9 @@ int scf_ast_add_const_var(scf_ast_t* ast, scf_node_t* parent, int type, const ui
        return 0;
 }
 
-int scf_function_signature(scf_ast_t* ast, scf_function_t* f)
+int scf_function_signature2(scf_string_t** ps, scf_ast_t* ast, scf_type_t* t, const char* fname, scf_vector_t* argv)
 {
        scf_string_t* s;
-       scf_type_t*   t = (scf_type_t*)f->node.parent;
-
        int ret;
        int i;
 
@@ -596,32 +594,22 @@ int scf_function_signature(scf_ast_t* ast, scf_function_t* f)
                        goto error;
        }
 
-       if (f->op_type >= 0) {
-               scf_operator_t* op = scf_find_base_operator_by_type(f->op_type);
-
-               if (!op->signature)
-                       goto error;
-
-               ret = scf_string_cat_cstr(s, op->signature);
-       } else
-               ret = scf_string_cat(s, f->node.w->text);
-
+       ret = scf_string_cat_cstr(s, fname);
        if (ret < 0)
                goto error;
        scf_logd("f signature: %s\n", s->data);
 
        if (t->node.type < SCF_STRUCT) {
-               if (f->signature)
-                       scf_string_free(f->signature);
-
-               f->signature = s;
+               *ps = s;
                return 0;
        }
 
-       if (f->argv) {
-               for (i = 0; i < f->argv->size; i++) {
-                       scf_variable_t* v   = f->argv->data[i];
-                       scf_type_t*     t_v = NULL;
+       if (argv) {
+               scf_variable_t* v;
+               scf_type_t*     t_v;
+
+               for (i = 0; i < argv->size; i++) {
+                       v  =        argv->data[i];
 
                        t_v = scf_block_find_type_type((scf_block_t*)t, v->type);
                        if (!t_v) {
@@ -657,14 +645,36 @@ int scf_function_signature(scf_ast_t* ast, scf_function_t* f)
 
        scf_logd("f signature: %s\n", s->data);
 
-       if (f->signature)
-               scf_string_free(f->signature);
-       f->signature = s;
+       *ps = s;
        return 0;
 
 error:
        scf_string_free(s);
-       return -1;
+       return ret;
+}
+
+int scf_function_signature(scf_ast_t* ast, scf_function_t* f, scf_vector_t* argv)
+{
+       char* fname = f->node.w->text->data;
+
+       if (f->op_type >= 0) {
+               scf_operator_t* op = scf_find_base_operator_by_type(f->op_type);
+
+               if (!op->signature)
+                       return -EINVAL;
+
+               fname = op->signature;
+       }
+
+       if (!argv)
+               argv = f->argv;
+
+       if (f->signature) {
+               scf_string_free(f->signature);
+               f->signature = NULL;
+       }
+
+       return scf_function_signature2(&f->signature, ast, (scf_type_t*)f->node.parent, fname, argv);
 }
 
 int scf_ast_find_proper_function(scf_function_t** pf, scf_ast_t* ast, scf_vector_t* fvec, scf_vector_t* argv)
index 8657eb960e934d1634154b6080f77a2da90dfed8..c749ace46bfb779b15691981e36d3ed5e00cb448 100644 (file)
@@ -78,7 +78,9 @@ int scf_ast_add_base_type(scf_ast_t* ast, scf_base_type_t* base_type);
 
 int scf_ast_add_file_block(scf_ast_t* ast, const char* path);
 
-int scf_function_signature(scf_ast_t* ast, scf_function_t* f);
+int scf_function_signature(scf_ast_t* ast, scf_function_t* f, scf_vector_t* argv);
+
+int scf_function_signature2(scf_string_t** ps, scf_ast_t* ast, scf_type_t* t, const char* fname, scf_vector_t* argv);
 
 int scf_ast_add_const_str(scf_ast_t* ast, scf_node_t* parent, scf_lex_word_t* w);
 int scf_ast_add_const_var(scf_ast_t* ast, scf_node_t* parent, int type, const uint64_t u64);
index 7b9160f04ae9a36343fd8277d91e2d6737820865..5327198464a98ad741be3d8f7491a834aaf45b3c 100644 (file)
@@ -11,6 +11,7 @@ static scf_operator_t base_operators[] =
        {".",         "p",    SCF_OP_POINTER,       1,  2,  SCF_OP_ASSOCIATIVITY_LEFT},
 
        {"va_start",  NULL,   SCF_OP_VA_START,      1,  2,  SCF_OP_ASSOCIATIVITY_LEFT},
+       {"va_copy",   NULL,   SCF_OP_VA_COPY,       1,  2,  SCF_OP_ASSOCIATIVITY_LEFT},
        {"va_arg",    NULL,   SCF_OP_VA_ARG,        1,  2,  SCF_OP_ASSOCIATIVITY_LEFT},
        {"va_end",    NULL,   SCF_OP_VA_END,        1,  1,  SCF_OP_ASSOCIATIVITY_LEFT},
        {"container", NULL,   SCF_OP_CONTAINER,     1,  3,  SCF_OP_ASSOCIATIVITY_LEFT},
index 72909501825d63869f9dea340d911d10c4a3e9e5..35784b6a5ef6038fb8881a8a69d77a66eabab0ab 100644 (file)
@@ -202,11 +202,16 @@ static int _scf_op_va_start(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, vo
        vptr->tmp_flag = 1;
 
        nptr = scf_node_alloc(NULL, vptr->type, vptr);
+
+       scf_variable_free(vptr);
+       vptr = NULL;
        if (!nptr)
                return -ENOMEM;
 
-       if (scf_node_add_child(parent, nptr) < 0)
+       if (scf_node_add_child(parent, nptr) < 0) {
+               scf_node_free(nptr);
                return -ENOMEM;
+       }
 
        srcs[0] = parent->nodes[0];
        srcs[1] = parent->nodes[1];
@@ -215,6 +220,15 @@ static int _scf_op_va_start(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, vo
        return _scf_3ac_code_srcN(d->_3ac_list_head, SCF_OP_VA_START, srcs, 3);
 }
 
+static int _scf_op_va_copy(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* data)
+{
+       assert(2 == nb_nodes);
+
+       scf_handler_data_t* d = data;
+
+       return _scf_3ac_code_srcN(d->_3ac_list_head, SCF_OP_VA_COPY, nodes, nb_nodes);
+}
+
 static int _scf_op_va_end(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* data)
 {
        assert(1 == nb_nodes);
@@ -2431,6 +2445,7 @@ scf_operator_handler_pt  __operator_handlers[SCF_N_3AC_OPS] =
        [SCF_OP_POINTER    ]  = _scf_op_pointer,
 
        [SCF_OP_VA_START]     = _scf_op_va_start,
+       [SCF_OP_VA_COPY ]     = _scf_op_va_copy,
        [SCF_OP_VA_ARG  ]     = _scf_op_va_arg,
        [SCF_OP_VA_END  ]     = _scf_op_va_end,
 
index 4cc8c43e047a37febeb6689710bbc37702888c26..741e1566381debdb595da3ac60f1e5237fb2565e 100644 (file)
@@ -1,4 +1,8 @@
 #include<stdio.h>
+#include<stdlib.h>
+#include<stdarg.h>
+#include<string.h>
+#include<stddef.h>
 
 int main()
 {
diff --git a/examples/offsetof.c b/examples/offsetof.c
new file mode 100644 (file)
index 0000000..911557d
--- /dev/null
@@ -0,0 +1,18 @@
+#include<stdio.h>
+#include<stdlib.h>
+#include<stdarg.h>
+#include<string.h>
+#include<stddef.h>
+
+struct A
+{
+       long  x;
+       int   y;
+       short z;
+};
+
+int main()
+{
+       printf("offsetof(A, z): %ld\n", offsetof(A, z));
+       return 0;
+}
index e38964b7403cac0d870751ac7b36e9ac22a0db96..9d81227a129000cab1b150312334a537c514f058 100644 (file)
@@ -206,11 +206,16 @@ int write(int fd, uint8_t* buf, intptr_t size);
 int scf_printf(const char* fmt, ...)
 {
        va_list ap;
+       va_list ap2;
 
        char buf[1024];
 
        va_start(ap, fmt);
-       int ret = scf_vsnprintf(buf, sizeof(buf) - 1, fmt, &ap);
+       va_copy(ap2, ap);
+
+       int ret = scf_vsnprintf(buf, sizeof(buf) - 1, fmt, &ap2);
+
+       va_end(ap2);
        va_end(ap);
 
        if (ret > 0) {
index 2abb52c3b29914e834732b8bdf27b127ac998223..81f8e19110aa05a0fdd7c118079f99b7579b4f49 100644 (file)
@@ -1963,7 +1963,6 @@ static int _x64_inst_pop_rets_handler(scf_native_t* ctx, scf_3ac_code_t* c)
 }
 
 /*
-
 struct va_list
 {
        uint8_t*  iptr;
@@ -2040,6 +2039,80 @@ static int _x64_inst_va_start_handler(scf_native_t* ctx, scf_3ac_code_t* c)
        return 0;
 }
 
+static int _x64_inst_va_copy_handler(scf_native_t* ctx, scf_3ac_code_t* c)
+{
+       scf_x64_context_t*  x64 = ctx->priv;
+       scf_function_t*     f   = x64->f;
+
+       if (!c->instructions) {
+               c->instructions = scf_vector_alloc();
+               if (!c->instructions)
+                       return -ENOMEM;
+       }
+
+       assert(2 == c->srcs->size);
+
+       scf_instruction_t*  inst  = NULL;
+       scf_register_t*     r0    = NULL;
+       scf_register_t*     r1    = NULL;
+       scf_register_t*     r     = NULL;
+
+       scf_3ac_operand_t*  ap0   = c->srcs->data[0];
+       scf_3ac_operand_t*  ap1   = c->srcs->data[1];
+       scf_x64_OpCode_t*   P2G   = x64_find_OpCode(SCF_X64_MOV, 8, 8, SCF_X64_E2G);
+       scf_x64_OpCode_t*   G2P   = x64_find_OpCode(SCF_X64_MOV, 8, 8, SCF_X64_G2E);
+       scf_variable_t*     v0    = ap0->dag_node->var;
+       scf_variable_t*     v1    = ap1->dag_node->var;
+
+       if (v0->bp_offset >= 0 || v1->bp_offset >= 0) {
+               scf_loge("\n");
+               return -1;
+       }
+
+       X64_SELECT_REG_CHECK(&r0, ap0->dag_node, c, f, 1);
+       X64_SELECT_REG_CHECK(&r1, ap1->dag_node, c, f, 1);
+
+       int ret = x64_select_free_reg(&r, c, f, 0);
+       if (ret < 0)
+               return ret;
+
+       // iptr: offset 0
+       inst = x64_make_inst_P2G(P2G, r, r1, 0);
+       X64_INST_ADD_CHECK(c, inst, NULL);
+
+       inst = x64_make_inst_G2P(G2P, r0, 0, r);
+       X64_INST_ADD_CHECK(c, inst, NULL);
+
+       // fptr: offset 8
+       inst = x64_make_inst_P2G(P2G, r, r1, 8);
+       X64_INST_ADD_CHECK(c, inst, NULL);
+
+       inst = x64_make_inst_G2P(G2P, r0, 8, r);
+       X64_INST_ADD_CHECK(c, inst, NULL);
+
+       // optr: offset 16
+       inst = x64_make_inst_P2G(P2G, r, r1, 16);
+       X64_INST_ADD_CHECK(c, inst, NULL);
+
+       inst = x64_make_inst_G2P(G2P, r0, 16, r);
+       X64_INST_ADD_CHECK(c, inst, NULL);
+
+       // ireg: offset 24
+       inst = x64_make_inst_P2G(P2G, r, r1, 24);
+       X64_INST_ADD_CHECK(c, inst, NULL);
+
+       inst = x64_make_inst_G2P(G2P, r0, 24, r);
+       X64_INST_ADD_CHECK(c, inst, NULL);
+
+       // freg: offset 32
+       inst = x64_make_inst_P2G(P2G, r, r1, 32);
+       X64_INST_ADD_CHECK(c, inst, NULL);
+
+       inst = x64_make_inst_G2P(G2P, r0, 32, r);
+       X64_INST_ADD_CHECK(c, inst, NULL);
+       return 0;
+}
+
 static int _x64_inst_va_end_handler(scf_native_t* ctx, scf_3ac_code_t* c)
 {
        scf_x64_context_t*  x64 = ctx->priv;
@@ -2223,6 +2296,7 @@ static x64_inst_handler_pt  x64_inst_handlers[] =
        [SCF_OP_NEG             ]  =  _x64_inst_neg_handler,
 
        [SCF_OP_VA_START    ]  =  _x64_inst_va_start_handler,
+       [SCF_OP_VA_COPY     ]  =  _x64_inst_va_copy_handler,
        [SCF_OP_VA_ARG      ]  =  _x64_inst_va_arg_handler,
        [SCF_OP_VA_END      ]  =  _x64_inst_va_end_handler,
 
index baf144bc9c33d9b21f7fb4ac555107e1c4106474..28a68ccc2626717455c940dd8c08fe832461f4b1 100644 (file)
@@ -1191,6 +1191,14 @@ static int _x64_rcg_va_start_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_g
        return x64_rcg_make(c, g, NULL, NULL);
 }
 
+static int _x64_rcg_va_copy_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_t* g)
+{
+       int ret = x64_rcg_make2(c, NULL, NULL);
+       if (ret < 0)
+               return ret;
+       return x64_rcg_make(c, g, NULL, NULL);
+}
+
 static int _x64_rcg_va_end_handler(scf_native_t* ctx, scf_3ac_code_t* c, scf_graph_t* g)
 {
        int ret = x64_rcg_make2(c, NULL, NULL);
@@ -1220,6 +1228,7 @@ static x64_rcg_handler_pt  x64_rcg_handlers[SCF_N_3AC_OPS] =
        [SCF_OP_NEG         ]  =  _x64_rcg_neg_handler,
 
        [SCF_OP_VA_START    ]  =  _x64_rcg_va_start_handler,
+       [SCF_OP_VA_COPY     ]  =  _x64_rcg_va_copy_handler,
        [SCF_OP_VA_ARG      ]  =  _x64_rcg_va_arg_handler,
        [SCF_OP_VA_END      ]  =  _x64_rcg_va_end_handler,
 
index 49a2187bb278a0ac4b799768c1fae5df6768348f..b8a66813648b359882ecd98203fa276f7ec60e1f 100644 (file)
@@ -9,7 +9,7 @@ typedef struct {
        scf_stack_t*      ls_exprs;
        scf_stack_t*      lp_exprs;
        scf_block_t*      parent_block;
-       scf_variable_t*   current_var;
+
        scf_type_t*       current_struct;
 
 } expr_module_data_t;
@@ -117,6 +117,9 @@ int _expr_add_var(scf_parse_t* parse, dfa_data_t* d)
        scf_logd("var: %s, member_flag: %d, line: %d\n", var->w->text->data, var->member_flag, var->w->line);
 
        node = scf_node_alloc(w, var->type, var);
+
+       scf_variable_free(var);
+       var = NULL;
        if (!node)
                return -ENOMEM;
 
@@ -133,14 +136,14 @@ int _expr_add_var(scf_parse_t* parse, dfa_data_t* d)
                return SCF_DFA_ERROR;
        }
 
-       if (var->type >= SCF_STRUCT) {
+       if (node->var->type >= SCF_STRUCT) {
 
-               int ret = scf_ast_find_type_type(&md->current_struct, parse->ast, var->type);
+               int ret = scf_ast_find_type_type(&md->current_struct, parse->ast, node->var->type);
                if (ret < 0)
                        return SCF_DFA_ERROR;
+
                assert(md->current_struct);
        }
-       md->current_var = var;
 
        free(id);
        id = NULL;
@@ -193,7 +196,7 @@ static int _expr_action_number(scf_dfa_t* dfa, scf_vector_t* words, void* data)
                                        return SCF_DFA_ERROR;
                                }
 
-                               if (scf_function_signature(parse->ast, f) < 0)
+                               if (scf_function_signature(parse->ast, f, NULL) < 0)
                                        return SCF_DFA_ERROR;
 
                                w->text->data[2] = '\0';
@@ -248,19 +251,18 @@ static int _expr_action_number(scf_dfa_t* dfa, scf_vector_t* words, void* data)
        }
 
        scf_variable_t* var = SCF_VAR_ALLOC_BY_TYPE(w, t, 1, nb_pointers, NULL);
-       if (!var) {
-               scf_loge("var '%s' alloc failed\n", w->text->data);
-               return SCF_DFA_ERROR;
-       }
+       if (!var)
+               return -ENOMEM;
 
-       scf_node_t* n = scf_node_alloc(w, var->type, var);
-       if (!n) {
-               scf_loge("var node '%s' alloc failed\n", w->text->data);
-               return SCF_DFA_ERROR;
-       }
+       scf_node_t* node = scf_node_alloc(w, var->type, var);
 
-       if (scf_expr_add_node(d->expr, n) < 0) {
-               scf_loge("add var node '%s' to expr failed\n", w->text->data);
+       scf_variable_free(var);
+       var = NULL;
+       if (!node)
+               return -ENOMEM;
+
+       if (scf_expr_add_node(d->expr, node) < 0) {
+               scf_node_free(node);
                return SCF_DFA_ERROR;
        }
 
@@ -416,38 +418,57 @@ static int _expr_action_rp_cast(scf_dfa_t* dfa, scf_vector_t* words, void* data)
        if (d->current_va_arg || d->current_va_copy)
                return SCF_DFA_NEXT_SYNTAX;
 
-       scf_variable_t* var       = NULL;
-       scf_node_t*     node_var  = NULL;
-       scf_node_t*     node_cast = NULL;
+       scf_variable_t* var  = NULL;
+       scf_node_t*     node = NULL;
+       scf_node_t*     cast = NULL;
+       scf_expr_t*     e    = NULL;
 
        var = SCF_VAR_ALLOC_BY_TYPE(id->type_w, id->type, id->const_flag, id->nb_pointers, id->func_ptr);
-       if (!var) {
-               scf_loge("var alloc failed\n");
+       if (!var)
                return SCF_DFA_ERROR;
-       }
 
-       node_var = scf_node_alloc(NULL, var->type, var);
-       if (!node_var) {
-               scf_loge("var node alloc failed\n");
+       node = scf_node_alloc(NULL, var->type, var);
+
+       scf_variable_free(var);
+       var = NULL;
+       if (!node)
                return SCF_DFA_ERROR;
-       }
 
-       node_cast = scf_node_alloc(id->type_w, SCF_OP_TYPE_CAST, NULL);
-       if (!node_cast) {
-               scf_loge("cast node alloc failed\n");
+       cast = scf_node_alloc(id->type_w, SCF_OP_TYPE_CAST, NULL);
+       if (!cast) {
+               scf_node_free(node);
                return SCF_DFA_ERROR;
        }
-       scf_node_add_child(node_cast, node_var);
 
-       // '(' lp action pushed a expr before
-       scf_expr_t* e = scf_stack_pop(md->lp_exprs);
-
-       scf_logd("type cast: d->expr: %p, d->expr->parent: %p, e: %p\n", d->expr, d->expr->parent, e);
+       int ret = scf_node_add_child(cast, node);
+       if (ret < 0) {
+               scf_node_free(cast);
+               scf_node_free(node);
+               return ret;
+       }
 
+       // '(' lp action pushed a expr before
+       e = scf_stack_pop(md->lp_exprs);
        assert(e);
 
-       scf_expr_add_node(e, node_cast);
+       ret = scf_expr_add_node(e, cast);
+       if (ret < 0) {
+               scf_node_free(cast);
+               scf_expr_free(e);
+               return ret;
+       }
+
        d->expr = e;
+       e = NULL;
+
+       if (node->var->type >= SCF_STRUCT) {
+
+               ret = scf_ast_find_type_type(&md->current_struct, parse->ast, node->var->type);
+               if (ret < 0)
+                       return SCF_DFA_ERROR;
+
+               assert(md->current_struct);
+       }
 
        scf_stack_pop(d->current_identities);
        free(id);
@@ -997,6 +1018,7 @@ static int _dfa_init_syntax_expr(scf_dfa_t* dfa)
        scf_dfa_node_add_child(rs,         binary_op);
        scf_dfa_node_add_child(rs,         unary_post);
        scf_dfa_node_add_child(rs,         rp);
+       scf_dfa_node_add_child(rp,         ls);
        scf_dfa_node_add_child(identity,   unary_post);
        scf_dfa_node_add_child(identity,   rs);
 
index 2ac87de32f675bf4d0880391af7acf4e23a48965..a26b15d95127f85ee81d327f5835961fee1469cb 100644 (file)
@@ -18,7 +18,80 @@ typedef struct {
 
 int _type_find_type(scf_dfa_t* dfa, dfa_identity_t* id);
 
-int _function_add_function(scf_dfa_t* dfa, dfa_data_t* d)
+
+int _function_add_rets(scf_function_t* f, dfa_data_t* d)
+{
+       dfa_identity_t*  id;
+       scf_variable_t*  v;
+
+       int void_flag = 0;
+
+       while (d->current_identities->size > 0) {
+
+               id = scf_stack_pop(d->current_identities);
+               if (!id)
+                       return SCF_DFA_ERROR;
+
+               if (!id->type) {
+                       assert(id->identity);
+
+                       scf_loge("%s:%d:%d, function return value type '%s' NOT found\n",
+                                       id->identity->file->data, id->identity->line, id->identity->pos,
+                                       id->identity->text->data);
+                       return SCF_DFA_ERROR;
+               }
+
+               if (SCF_VAR_VOID == id->type->node.type && 0 == id->nb_pointers)
+                       void_flag = 1;
+
+               f->extern_flag |= id->extern_flag;
+               f->static_flag |= id->static_flag;
+               f->inline_flag |= id->inline_flag;
+
+               if (f->extern_flag && (f->static_flag || f->inline_flag)) {
+                       scf_loge("'extern' function can't be 'static' or 'inline'\n");
+                       return SCF_DFA_ERROR;
+               }
+
+               v  = SCF_VAR_ALLOC_BY_TYPE(id->type_w, id->type, id->const_flag, id->nb_pointers, NULL);
+               free(id);
+               id = NULL;
+
+               if (!v)
+                       return SCF_DFA_ERROR;
+
+               if (scf_vector_add(f->rets, v) < 0) {
+                       scf_variable_free(v);
+                       return SCF_DFA_ERROR;
+               }
+       }
+
+       assert(f->rets->size > 0);
+
+       if (void_flag && 1 != f->rets->size) {
+               scf_loge("void function must have no other return value\n");
+               return SCF_DFA_ERROR;
+       }
+
+       f->void_flag = void_flag;
+
+       if (f->rets->size > 4) {
+               scf_loge("function return values must NOT more than 4!\n");
+               return SCF_DFA_ERROR;
+       }
+
+       int i;
+       int j;
+       for (i = 0; i < f->rets->size / 2;  i++) {
+               j  =        f->rets->size - 1 - i;
+
+               SCF_XCHG(f->rets->data[i], f->rets->data[j]);
+       }
+
+       return 0;
+}
+
+int _function_add_function(scf_dfa_t* dfa, dfa_data_t* d, scf_lex_word_t* lp)
 {
        scf_parse_t*     parse = dfa->priv;
        scf_ast_t*       ast   = parse->ast;
@@ -40,14 +113,16 @@ int _function_add_function(scf_dfa_t* dfa, dfa_data_t* d)
                        return -ENOMEM;
 
        } else {
-               id = scf_stack_pop(d->current_identities);
-
-               if (!id || !id->identity) {
-                       scf_loge("function identity not found\n");
+               id = scf_stack_top(d->current_identities);
+               if (!id) {
+                       scf_loge("%s:%d:%d, lost 'void' when declare function pointer\n", lp->file->data, lp->line, lp->pos);
                        return SCF_DFA_ERROR;
                }
 
-               name = id->identity;
+               if (id->identity)
+                       name = id->identity;
+               else
+                       name = id->type_w;
        }
 
        uint32_t local_flag  = 0;
@@ -103,7 +178,7 @@ int _function_add_function(scf_dfa_t* dfa, dfa_data_t* d)
                        v_pf = d->current_var;
 
                assert(d->current_identities->size > 0);
-               id0  = d->current_identities->data[0];
+               id0 = d->current_identities->data[0];
 
                if (id0->typedef_flag) {
                        id0->typedef_flag = 0;
@@ -131,72 +206,18 @@ int _function_add_function(scf_dfa_t* dfa, dfa_data_t* d)
                return SCF_DFA_ERROR;
        f->member_flag = member_flag;
 
-       if (id) {
+       if (id && d->current_identities->size > 1) {
+               scf_stack_pop(d->current_identities);
                free(id);
-               id = NULL;
        }
+       id = NULL;
 
        scf_logi("s->size: %d, function: %s(), line: %d, member_flag: %d\n", s->size, f->node.w->text->data, f->node.w->line, f->member_flag);
 
-       int void_flag = 0;
-
-       while (d->current_identities->size > 0) {
-
-               id = scf_stack_pop(d->current_identities);
-
-               if (!id || !id->type || !id->type_w) {
-                       scf_loge("function return value type NOT found\n");
-                       return SCF_DFA_ERROR;
-               }
-
-               if (SCF_VAR_VOID == id->type->node.type && 0 == id->nb_pointers)
-                       void_flag = 1;
-
-               f->extern_flag |= id->extern_flag;
-               f->static_flag |= id->static_flag;
-               f->inline_flag |= id->inline_flag;
-
-               if (f->extern_flag && (f->static_flag || f->inline_flag)) {
-                       scf_loge("'extern' function can't be 'static' or 'inline'\n");
-                       return SCF_DFA_ERROR;
-               }
-
-               v  = SCF_VAR_ALLOC_BY_TYPE(id->type_w, id->type, id->const_flag, id->nb_pointers, NULL);
-               free(id);
-               id = NULL;
-
-               if (!v) {
-                       scf_function_free(f);
-                       return SCF_DFA_ERROR;
-               }
-
-               if (scf_vector_add(f->rets, v) < 0) {
-                       scf_variable_free(v);
-                       scf_function_free(f);
-                       return SCF_DFA_ERROR;
-               }
-       }
-
-       assert(f->rets->size > 0);
-
-       if (void_flag && 1 != f->rets->size) {
-               scf_loge("void function must have no other return value\n");
-               return SCF_DFA_ERROR;
-       }
-
-       f->void_flag = void_flag;
-
-       if (f->rets->size > 4) {
-               scf_loge("function return values must NOT more than 4!\n");
-               return SCF_DFA_ERROR;
-       }
-
-       int i;
-       int j;
-       for (i = 0; i < f->rets->size / 2;  i++) {
-               j  =        f->rets->size - 1 - i;
-
-               SCF_XCHG(f->rets->data[i], f->rets->data[j]);
+       int ret = _function_add_rets(f, d);
+       if (ret < 0) {
+               scf_function_free(f);
+               return ret;
        }
 
        if (v_pf) {
@@ -325,11 +346,11 @@ int _function_add_arg(scf_dfa_t* dfa, dfa_data_t* d)
                arg->dimentions = NULL;
        }
 
-       arg->const_literal_flag = 0;
-
        scf_logi("s->size: %d, fd->f: %s(), fd->argc: %d, arg->nb_pointers: %d, arg->nb_dimentions: %d\n",
                        s->size, fd->f->node.w->text->data, fd->argc, arg->nb_pointers, arg->nb_dimentions);
 
+       arg->const_literal_flag = 0;
+
        assert(scf_vector_find(fd->f->scope->vars, arg));
 
        scf_vector_add(fd->f->argv, arg);
@@ -411,6 +432,7 @@ static int _function_action_pf_rp(scf_dfa_t* dfa, scf_vector_t* words, void* dat
 static int _function_action_lp(scf_dfa_t* dfa, scf_vector_t* words, void* data)
 {
        scf_parse_t*     parse = dfa->priv;
+       scf_lex_word_t*  w     = words->data[words->size - 1];
        dfa_data_t*      d     = data;
        scf_stack_t*     s     = d->module_datas[dfa_module_function.index];
        dfa_fun_data_t*  fd    = calloc(1, sizeof(dfa_fun_data_t));
@@ -427,11 +449,12 @@ static int _function_action_lp(scf_dfa_t* dfa, scf_vector_t* words, void* data)
        if (d->pf_pointers <= 0)
                d->current_var = NULL;
 
-       ret = _function_add_function(dfa, d);
+       ret = _function_add_function(dfa, d, w);
        if (ret < 0)
                return ret;
 
        d->current_var = NULL;
+       d->arg_flag    = 1;
 
        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);
@@ -468,6 +491,8 @@ static int _function_action_rp(scf_dfa_t* dfa, scf_vector_t* words, void* data)
 
        scf_logi("f: %s(), fd->nb_lps: %d, fd->nb_rps: %d\n", f->node.w->text->data, fd->nb_lps, fd->nb_rps);
 
+       d->arg_flag = 0;
+
        if (_function_add_arg(dfa, d) < 0)
                return SCF_DFA_ERROR;
 
@@ -695,6 +720,7 @@ static int _dfa_init_syntax_function(scf_dfa_t* dfa)
        scf_dfa_node_add_child(identity,  assign);
        scf_dfa_node_add_child(rs,        pf_rp);
 
+       scf_dfa_node_add_child(pf_star,   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 48d9ae9da0aeef175b455d3ad11d0faa03328bc4..371f52387a623aa22a56010924d94ae0778bea14 100644 (file)
@@ -4,6 +4,27 @@
 
 extern scf_dfa_module_t dfa_module_identity;
 
+static scf_key_word_t  future_key_words[] =
+{
+       {SCF_CSTR("_Noreturn"), -1},
+};
+
+void warning_future_key_word(scf_lex_word_t* w)
+{
+       scf_key_word_t* key;
+       int i;
+
+       for (i  = 0; i < sizeof(future_key_words) / sizeof(future_key_words[0]); i++) {
+               key = &future_key_words[i];
+
+               if (w->text->len == key->len && !memcmp(w->text->data, key->text, key->len)) {
+                       scf_logw("%s:%d:%d, '%s' is a key word of future std C\n",
+                                       w->file->data, w->line, w->pos, w->text->data);
+                       break;
+               }
+       }
+}
+
 static int _identity_action_identity(scf_dfa_t* dfa, scf_vector_t* words, void* data)
 {
        scf_lex_word_t*  w = words->data[words->size - 1];
@@ -12,6 +33,8 @@ static int _identity_action_identity(scf_dfa_t* dfa, scf_vector_t* words, void*
 
        scf_logd("w: '%s'\n", w->text->data);
 
+       warning_future_key_word(w);
+
        dfa_identity_t* id  = calloc(1, sizeof(dfa_identity_t));
        if (!id)
                return SCF_DFA_ERROR;
index 74b94295d64b31b7321c6681a1449aaa254ffd5b..8523c580b5dc5fe642de63333348d2c7d4a00cdd 100644 (file)
@@ -6,6 +6,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);
 
+void warning_future_key_word(scf_lex_word_t* w);
+
 typedef struct {
        int type;
        int n;
@@ -38,8 +40,10 @@ static type_filter_t  base_type_filters[] =
 
 static int _base_type_filter(scf_dfa_t* dfa, scf_vector_t* words, scf_stack_t* s)
 {
-       if (s->size <= 1)
+       if (s->size <= 1) {
+               scf_logw("s->size: %d\n", s->size);
                return 0;
+       }
 
        scf_parse_t*     parse = dfa->priv;
        scf_ast_t*       ast   = parse->ast;
@@ -305,6 +309,10 @@ static int _type_action_identity(scf_dfa_t* dfa, scf_vector_t* words, void* data
        dfa_identity_t*  id    = NULL;
        int ret;
 
+       warning_future_key_word(w);
+
+       scf_logi("w: %s\n", w->text->data);
+
        if (s->size > 0) {
                type = scf_stack_top(s);
 
@@ -359,13 +367,30 @@ static int _type_action_identity(scf_dfa_t* dfa, scf_vector_t* words, void* data
 
 static int _type_action_star(scf_dfa_t* dfa, scf_vector_t* words, void* data)
 {
-       dfa_data_t*      d  = data;
-       dfa_identity_t*  id = scf_stack_top(d->current_identities);
+       scf_parse_t*     parse = dfa->priv;
+       dfa_data_t*      d     = data;
+       dfa_identity_t*  id    = scf_stack_top(d->current_identities);
+       int ret;
 
        assert(id);
 
        if (!id->type) {
-               int ret = _type_find_type(dfa, id);
+
+               if (words->size >= 3) {
+                       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, id);
                if (ret < 0) {
                        scf_loge("\n");
                        return ret;
@@ -525,6 +550,7 @@ static int _dfa_init_syntax_type(scf_dfa_t* dfa)
        // const pointer, like 'uint8_t* const p'
        scf_dfa_node_add_child(star,      vconst);
        scf_dfa_node_add_child(vconst,    var_name);
+       scf_dfa_node_add_child(vconst,    star);
 
        // multi-return-value function
        scf_dfa_node_add_child(base_type, comma);
index 06e718a54ce47f9594ef1d538c20fa20b90fdf23..6e8011a2a875708f8dfea332d5d41d453abcb1c6 100644 (file)
@@ -14,6 +14,7 @@ static int _va_arg_action_start(scf_dfa_t* dfa, scf_vector_t* words, void* data)
        scf_lex_word_t*  w     = words->data[words->size - 1];
 
        if (d->current_va_start
+                       || d->current_va_copy
                        || d->current_va_arg
                        || d->current_va_end) {
                scf_loge("recursive 'va_start' in file: %s, line %d\n", w->file->data, w->line);
@@ -33,10 +34,27 @@ static int _va_arg_action_start(scf_dfa_t* dfa, scf_vector_t* words, void* data)
 
 static int _va_arg_action_copy(scf_dfa_t* dfa, scf_vector_t* words, void* data)
 {
+       scf_parse_t*     parse = dfa->priv;
+       dfa_data_t*      d     = data;
        scf_lex_word_t*  w     = words->data[words->size - 1];
 
-       scf_loge("%s:%d:%d, NOT support 'va_copy'\n", w->file->data, w->line, w->pos);
-       return SCF_DFA_ERROR;
+       if (d->current_va_start
+                       || d->current_va_copy
+                       || d->current_va_arg
+                       || d->current_va_end) {
+               scf_loge("recursive 'va_copy' in file: %s, line %d\n", w->file->data, w->line);
+               return SCF_DFA_ERROR;
+       }
+
+       scf_node_t* node = scf_node_alloc(w, SCF_OP_VA_COPY, NULL);
+       if (!node)
+               return SCF_DFA_ERROR;
+
+       scf_node_add_child((scf_node_t*)parse->ast->current_block, node);
+
+       d->current_va_copy = node;
+
+       return SCF_DFA_NEXT_WORD;
 }
 
 static int _va_arg_action_arg(scf_dfa_t* dfa, scf_vector_t* words, void* data)
@@ -46,6 +64,7 @@ static int _va_arg_action_arg(scf_dfa_t* dfa, scf_vector_t* words, void* data)
        scf_lex_word_t*  w     = words->data[words->size - 1];
 
        if (d->current_va_start
+                       || d->current_va_copy
                        || d->current_va_arg
                        || d->current_va_end) {
                scf_loge("recursive 'va_arg' in file: %s, line %d\n", w->file->data, w->line);
@@ -73,6 +92,7 @@ static int _va_arg_action_end(scf_dfa_t* dfa, scf_vector_t* words, void* data)
        scf_lex_word_t*  w     = words->data[words->size - 1];
 
        if (d->current_va_start
+                       || d->current_va_copy
                        || d->current_va_arg
                        || d->current_va_end) {
                scf_loge("recursive 'va_end' in file: %s, line %d\n", w->file->data, w->line);
@@ -97,6 +117,7 @@ static int _va_arg_action_lp(scf_dfa_t* dfa, scf_vector_t* words, void* data)
        scf_lex_word_t*  w     = words->data[words->size - 1];
 
        assert(d->current_va_start
+                       || d->current_va_copy
                        || d->current_va_arg
                        || d->current_va_end);
 
@@ -184,8 +205,8 @@ static int _va_arg_action_fmt(scf_dfa_t* dfa, scf_vector_t* words, void* data)
                        && SCF_VAR_I8 != fmt->type
                        && SCF_VAR_U8 != fmt->type) {
 
-               scf_loge("format string %s is not 'char*' or 'int8*' or 'uint8*' type\n", w->text->data);
-               return SCF_DFA_ERROR;
+               scf_logw("format string %s is not 'char*' or 'int8*' or 'uint8*' type\n", w->text->data);
+               return SCF_DFA_NEXT_SYNTAX;
        }
 
        if (scf_variable_nb_pointers(fmt) != 1) {
index 7f9028712dbd00ad8b91d0085b210d5e1bc87583..a2af0c781e5d72f96f4207d7efda870b9b371e5e 100644 (file)
@@ -46,146 +46,169 @@ static int _var_add_var(scf_dfa_t* dfa, dfa_data_t* d)
        scf_ast_t*       ast   = parse->ast;
        dfa_identity_t*  id    = scf_stack_top(d->current_identities);
        dfa_identity_t*  id0   = NULL;
+       scf_lex_word_t*  w     = NULL;
        scf_variable_t*  v     = NULL;
        scf_type_t*      t     = NULL;
 
-       if (id && id->identity) {
+       if (id) {
+               if (id->identity) {
+                       w = id->identity;
 
-               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;
+                       v = scf_scope_find_variable(ast->current_block->scope, w->text->data);
+                       if (v) {
+                               scf_loge("repeated declare var '%s', line: %d\n", w->text->data, w->line);
+                               return SCF_DFA_ERROR;
+                       }
                }
+       }
 
-               assert(d->current_identities->size >= 2);
+       // anonymous var only used in function args!!
+       if (!w && !d->arg_flag)
+               return 0;
 
-               id0 = d->current_identities->data[0];
+       assert(d->current_identities->size >= 1);
+       id0 =  d->current_identities->data[0];
 
-               assert(id0 && id0->type);
+       assert(id0 && id0->type);
 
-               t = id0->type;
+       t = id0->type;
 
-               int   const_flag  = id0->const_flag;
-               int   nb_pointers = id0->nb_pointers;
-               void* func_ptr    = id0->func_ptr;
+       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 (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 (!func_ptr)
+                       func_ptr = id0->type_def->func_ptr;
+       }
 
-               if (d->pf_pointers > 0) {
-                       nb_pointers = d->pf_pointers;
+       if (d->pf_pointers > 0) {
+               nb_pointers = d->pf_pointers;
 
-                       t = scf_block_find_type_type(ast->current_block, SCF_FUNCTION_PTR);
-               }
+               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_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;
-               }
+       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;
-                       b = (scf_block_t*)b->node.parent;
-               }
+       scf_block_t* b = ast->current_block;
+       while (b) {
+               if (b->node.type >= SCF_STRUCT || SCF_FUNCTION == b->node.type)
+                       break;
 
-               uint32_t global_flag;
-               uint32_t local_flag;
-               uint32_t member_flag;
+               b = (scf_block_t*)b->node.parent;
+       }
 
-               if (!b) {
-                       local_flag  = 0;
-                       global_flag = 1;
-                       member_flag = 0;
+       uint32_t global_flag;
+       uint32_t local_flag;
+       uint32_t member_flag;
 
-               } else if (SCF_FUNCTION == b->node.type) {
-                       local_flag  = 1;
-                       global_flag = 0;
-                       member_flag = 0;
+       if (!b) {
+               local_flag  = 0;
+               global_flag = 1;
+               member_flag = 0;
 
-               } else if (b->node.type >= SCF_STRUCT) {
-                       local_flag  = 0;
-                       global_flag = 0;
-                       member_flag = 1;
+       } else if (SCF_FUNCTION == b->node.type) {
+               local_flag  = 1;
+               global_flag = 0;
+               member_flag = 0;
 
-                       if (0 == nb_pointers && t->node.type >= SCF_STRUCT) {
-                               // if not pointer var, check if define recursive struct/union/class var
+       } else if (b->node.type >= SCF_STRUCT) {
+               local_flag  = 0;
+               global_flag = 0;
+               member_flag = 1;
 
-                               if (_check_recursive((scf_type_t*)b, t, id->identity) < 0) {
+               if (0 == nb_pointers && t->node.type >= SCF_STRUCT) {
+                       // if not pointer var, check if define recursive struct/union/class var
 
-                                       scf_loge("recursive define when define var '%s', line: %d\n",
-                                                       id->identity->text->data, id->identity->line);
-                                       return SCF_DFA_ERROR;
-                               }
-                       }
-               }
+                       if (_check_recursive((scf_type_t*)b, t, w) < 0) {
 
-               if (id0->extern_flag) {
-                       if (!global_flag) {
-                               scf_loge("extern var must be global.\n");
+                               scf_loge("%s:%d:%d, recursive define when define var '%s'\n",
+                                               w->file->data, w->line, w->pos, w->text->data);
                                return SCF_DFA_ERROR;
                        }
+               }
+       }
 
-                       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 (id0->extern_flag) {
+               if (!global_flag) {
+                       scf_loge("%s:%d:%d, extern var '%s' MUST be global.\n", w->file->data, w->line, w->pos, w->text->data);
+                       return SCF_DFA_ERROR;
                }
 
-               v = SCF_VAR_ALLOC_BY_TYPE(id->identity, t, const_flag, nb_pointers, func_ptr);
-               if (!v) {
-                       scf_loge("alloc var failed\n");
+               v = scf_block_find_variable(ast->current_block, w->text->data);
+               if (v) {
+                       scf_loge("%s:%d:%d, extern var '%s' already declared, first here: %s:%d:%d\n",
+                                       w->file->data, w->line, w->pos, w->text->data,
+                                       v->w->file->data,
+                                       v->w->line,
+                                       v->w->pos);
                        return SCF_DFA_ERROR;
                }
-               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;
+       v = SCF_VAR_ALLOC_BY_TYPE(w, t, const_flag, nb_pointers, func_ptr);
+       if (!v)
+               return SCF_DFA_ERROR;
 
-               if (id0->type_def) {
-                       int i;
-                       scf_dimention_t* dim;
+       v->local_flag   = local_flag;
+       v->global_flag  = global_flag;
+       v->member_flag  = member_flag;
 
-                       for (i  = 0; i < id0->type_def->nb_dimentions; i++) {
-                               dim =       &id0->type_def->dimentions[i];
+       v->static_flag  = id0->static_flag;
+       v->extern_flag  = id0->extern_flag;
+       v->typedef_flag = id0->typedef_flag;
 
-                               scf_variable_add_array_dimention(v, dim->num);
-                       }
+       if (id0->type_def) {
+               int i;
+               scf_dimention_t* dim;
+
+               for (i  = 0; i < id0->type_def->nb_dimentions; i++) {
+                       dim =       &id0->type_def->dimentions[i];
 
-                       v->const_literal_flag = id0->type_def->nb_dimentions > 0;
+                       scf_variable_add_array_dimention(v, dim->num);
                }
 
-               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);
+               v->const_literal_flag = id0->type_def->nb_dimentions > 0;
+       }
+
+#if 1
+       scf_logi("typedef_flag: %u, type: %d, nb_pointers: %d, nb_dimentions: %d",
+                       v->typedef_flag, v->type, v->nb_pointers, v->nb_dimentions);
 
-               scf_scope_push_var(ast->current_block->scope, v);
+       if (v->w)
+               printf(", var: '%s', line:%d, pos:%d", v->w->text->data, v->w->line, v->w->pos);
+       else
+               printf(", var: 'anonymous', line:%d, pos:%d", id0->type_w->line, id0->type_w->pos);
 
-               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;
+       printf(", local: %d, global: %d, member: %d, extern: %d, static: %d\n\n",
+                       v->local_flag,  v->global_flag, v->member_flag,
+                       v->extern_flag, v->static_flag);
+#endif
+
+       scf_scope_push_var(ast->current_block->scope, v);
+
+       d->current_var    = v;
+       d->current_var_w  = w;
+       id0->nb_pointers  = 0;
+       id0->const_flag   = 0;
+       id0->static_flag  = 0;
+       id0->extern_flag  = 0;
+
+       if (d->current_identities->size >= 2) {
 
                scf_stack_pop(d->current_identities);
+
                free(id);
                id = NULL;
        }
@@ -585,23 +608,25 @@ static int _dfa_init_module_var(scf_dfa_t* dfa)
 
 static int _dfa_init_syntax_var(scf_dfa_t* dfa)
 {
-       SCF_DFA_GET_MODULE_NODE(dfa, var,    comma,     comma);
-       SCF_DFA_GET_MODULE_NODE(dfa, var,    semicolon, semicolon);
+       SCF_DFA_GET_MODULE_NODE(dfa, var,        comma,     comma);
+       SCF_DFA_GET_MODULE_NODE(dfa, var,        semicolon, semicolon);
 
-       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);
+       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);
 
-       SCF_DFA_GET_MODULE_NODE(dfa, var,    colon,     colon);
-       SCF_DFA_GET_MODULE_NODE(dfa, var,    bits,      bits);
+       SCF_DFA_GET_MODULE_NODE(dfa, var,        colon,     colon);
+       SCF_DFA_GET_MODULE_NODE(dfa, var,        bits,      bits);
 
-       SCF_DFA_GET_MODULE_NODE(dfa, type,   star,      star);
-       SCF_DFA_GET_MODULE_NODE(dfa, type,   identity,  identity);
+       SCF_DFA_GET_MODULE_NODE(dfa, type,       star,      star);
+       SCF_DFA_GET_MODULE_NODE(dfa, type,       identity,  identity);
+       SCF_DFA_GET_MODULE_NODE(dfa, type,       base_type, base_type);
+       SCF_DFA_GET_MODULE_NODE(dfa, identity,   identity,  type_name);
 
-       SCF_DFA_GET_MODULE_NODE(dfa, expr,   entry,     expr);
+       SCF_DFA_GET_MODULE_NODE(dfa, expr,       entry,     expr);
 
-       SCF_DFA_GET_MODULE_NODE(dfa, init_data, entry,  init_data);
-       SCF_DFA_GET_MODULE_NODE(dfa, init_data, rb,     init_rb);
+       SCF_DFA_GET_MODULE_NODE(dfa, init_data,  entry,     init_data);
+       SCF_DFA_GET_MODULE_NODE(dfa, init_data,  rb,        init_rb);
 
 
        scf_dfa_node_add_child(identity,  comma);
@@ -617,6 +642,11 @@ static int _dfa_init_syntax_var(scf_dfa_t* dfa)
        scf_dfa_node_add_child(rs,        comma);
        scf_dfa_node_add_child(rs,        semicolon);
 
+       // anonymous array var, used for function args.
+       scf_dfa_node_add_child(base_type, ls);
+       scf_dfa_node_add_child(type_name, ls);
+       scf_dfa_node_add_child(star,      ls);
+
        // bits
        scf_dfa_node_add_child(identity,  colon);
        scf_dfa_node_add_child(colon,     bits);
index cfa654c6043c65757d8d749fd16630809a6bea85..0ae1c0ab0ad719a10727c823274aa812a80d5901 100644 (file)
@@ -164,8 +164,8 @@ static int _scf_op_const_array_index(scf_ast_t* ast, scf_node_t** nodes, int nb_
        assert(v0);
 
        if (scf_variable_nb_pointers(v0) <= 0) {
-               scf_loge("index out\n");
-               return -1;
+//             scf_loge("index out\n");
+//             return -1;
        }
 
        scf_handler_data_t* d = data;
@@ -509,6 +509,66 @@ static int _scf_op_const_dereference(scf_ast_t* ast, scf_node_t** nodes, int nb_
 
 static int _scf_op_const_address_of(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* data)
 {
+       assert(1 == nb_nodes);
+
+       scf_node_t*      child  = nodes[0];
+       scf_node_t*      parent = nodes[0]->parent;
+       scf_variable_t*  result = _scf_operand_get(parent);
+       scf_variable_t*  type;
+       scf_variable_t*  member;
+       scf_variable_t*  r = NULL;
+
+       while (SCF_OP_EXPR == child->type)
+               child = child->nodes[0];
+
+       if (SCF_OP_POINTER == child->type) {
+               assert(2 == child->nb_nodes);
+
+               type   = _scf_operand_get(child->nodes[0]);
+               member = _scf_operand_get(child->nodes[1]);
+
+               if (scf_variable_const(type)) {
+
+                       r = scf_variable_ref(result);
+
+                       r->data.u64   = type->data.u64 + member->offset;
+                       r->const_flag = 1;
+                       r->const_literal_flag = 1;
+
+                       scf_node_free_data(parent);
+
+                       parent->type = r->type;
+                       parent->var  = r;
+               }
+
+       } else if (SCF_OP_ARRAY_INDEX == child->type) {
+               assert(2 == child->nb_nodes);
+
+               type   = _scf_operand_get(child->nodes[0]);
+               member = _scf_operand_get(child->nodes[1]);
+
+               if (scf_variable_const(type)
+                               && !type->global_flag
+                               && !type->member_flag
+                               && !type->local_flag
+                               && scf_variable_const_integer(member)) {
+
+                       r = scf_variable_ref(result);
+
+                       r->data.u64   = type->data.u64 + member->data.u64 * type->data_size;
+                       r->const_flag = 1;
+                       r->const_literal_flag = 1;
+
+                       scf_node_free_data(parent);
+
+                       parent->type = r->type;
+                       parent->var  = r;
+
+                       scf_logd("type->data.p: %p, type->data_size: %d, member->data.u64: %ld, r->data.p: %p\n",
+                                       type->data.p, type->data_size, member->data.u64, r->data.p);
+               }
+       }
+
        return 0;
 }
 
@@ -549,12 +609,15 @@ static int _scf_op_const_type_cast(scf_ast_t* ast, scf_node_t** nodes, int nb_no
                                scf_loge("\n");
                                return ret;
                        }
+
+                       r->data_size  = result->data_size;
                        r->const_flag = 1;
 
                        if (parent->w)
                                SCF_XCHG(r->w, parent->w);
 
                        scf_node_free_data(parent);
+
                        parent->type = r->type;
                        parent->var  = r;
                }
@@ -919,6 +982,11 @@ static int _scf_op_const_va_start(scf_ast_t* ast, scf_node_t** nodes, int nb_nod
        return 0;
 }
 
+static int _scf_op_const_va_copy(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* data)
+{
+       return 0;
+}
+
 static int _scf_op_const_va_arg(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* data)
 {
        return 0;
@@ -939,6 +1007,7 @@ scf_operator_handler_pt  const_operator_handlers[SCF_N_OPS] =
        [SCF_OP_NEW        ]  =   _scf_op_const_new,
 
        [SCF_OP_VA_START   ]  =   _scf_op_const_va_start,
+       [SCF_OP_VA_COPY    ]  =   _scf_op_const_va_copy,
        [SCF_OP_VA_ARG     ]  =   _scf_op_const_va_arg,
        [SCF_OP_VA_END     ]  =   _scf_op_const_va_end,
 
index 9918ff6d0caf49a3465223e6fc11b1c2f449b1c0..a049e1364dcae37ca4f7353e3886887bcbc69f80 100644 (file)
@@ -762,15 +762,27 @@ static int _scf_op_semantic_new(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes
        }
 
        ret = _semantic_find_proper_function(ast, class, "__init", argv, &finit);
-       scf_vector_free(argv);
-
        if (ret < 0) {
-               scf_loge("init function of class '%s' not found\n", v0->w->text->data);
+               scf_string_t* signature = NULL;
+
+               ret = scf_function_signature2(&signature, ast, class, "__init", argv);
+
+               if (signature) {
+                       scf_loge("init function '%s' of class '%s' not found\n", signature->data, v0->w->text->data);
+
+                       scf_string_free(signature);
+               } else
+                       scf_loge("init function '__init' of class '%s' not found\n", v0->w->text->data);
+
+               scf_vector_free(argv);
                scf_node_free(nthis);
                return -1;
        }
        v0->func_ptr = finit;
 
+       scf_vector_free(argv);
+       argv = NULL;
+
        ret = _semantic_add_var(&nsize, ast, parent, v0->w, SCF_VAR_INT, 1, 0, NULL);
        if (ret < 0) {
                scf_node_free(nthis);
@@ -3075,6 +3087,16 @@ static int _scf_op_semantic_va_start(scf_ast_t* ast, scf_node_t** nodes, int nb_
        return 0;
 }
 
+static int _scf_op_semantic_va_copy(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* data)
+{
+       if (2 != nb_nodes) {
+               scf_loge("\n");
+               return -1;
+       }
+
+       return 0;
+}
+
 static int _scf_op_semantic_va_arg(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* data)
 {
        if (2 != nb_nodes) {
@@ -3094,7 +3116,6 @@ static int _scf_op_semantic_va_arg(scf_ast_t* ast, scf_node_t** nodes, int nb_no
                assert(t);
 
                scf_variable_t* r = SCF_VAR_ALLOC_BY_TYPE(nodes[0]->parent->w, t, 0, v->nb_pointers, v->func_ptr);
-
                if (!r)
                        return -ENOMEM;
 
@@ -3122,6 +3143,7 @@ scf_operator_handler_pt  semantic_operator_handlers[SCF_N_OPS] =
        [SCF_OP_NEW        ]  =  _scf_op_semantic_new,
 
        [SCF_OP_VA_START   ]  =  _scf_op_semantic_va_start,
+       [SCF_OP_VA_COPY    ]  =  _scf_op_semantic_va_copy,
        [SCF_OP_VA_ARG     ]  =  _scf_op_semantic_va_arg,
        [SCF_OP_VA_END     ]  =  _scf_op_semantic_va_end,
 
index 20e6636b463425cb8939ad590ad120f62dd66c74..bc3a458f466253846e6c88f669d68d20902c4c62 100644 (file)
@@ -1856,7 +1856,7 @@ static int _scf_parse_add_text_relas(scf_parse_t* parse, scf_elf_context_t* elf,
                for (j = 0; j < f->text_relas->size; j++) {
                        r  =        f->text_relas->data[j];
 
-                       if (scf_function_signature(parse->ast, r->func) < 0) {
+                       if (scf_function_signature(parse->ast, r->func, NULL) < 0) {
                                scf_loge("\n");
                                goto error;
                        }
@@ -2144,7 +2144,7 @@ int64_t scf_parse_fill_code2(scf_parse_t* parse, scf_vector_t* functions, scf_ve
                                return ret;
                }
 
-               if (scf_function_signature(parse->ast, f) < 0)
+               if (scf_function_signature(parse->ast, f, NULL) < 0)
                        return -ENOMEM;
 
                int ret = _fill_function_inst(code, f, offset, parse);
index cff60ce5d3e484f9eed66ba1542c6b369fb0a9f9..1e403fec2c616aa616378f0cfec4ff180e0dec92 100644 (file)
@@ -108,6 +108,7 @@ struct dfa_data_s {
        uint32_t             extern_flag:1;
        uint32_t             static_flag:1;
        uint32_t             inline_flag:1;
+       uint32_t             arg_flag:1;
 
        uint32_t             var_semicolon_flag:1;
 
diff --git a/sysroot/include/stddef.h b/sysroot/include/stddef.h
new file mode 100644 (file)
index 0000000..526df4e
--- /dev/null
@@ -0,0 +1,27 @@
+#ifndef _STDDEF_H
+#define _STDDEF_H
+
+#if __cplusplus >= 201103L
+#define NULL nullptr
+#elif defined(__cplusplus)
+#define NULL 0L
+#else
+//#define NULL ((void*)0)
+#endif
+
+#define __NEED_ptrdiff_t
+#define __NEED_size_t
+#define __NEED_wchar_t
+#if __STDC_VERSION__ >= 201112L || __cplusplus >= 201103L
+#define __NEED_max_align_t
+#endif
+
+#include <bits/alltypes.h>
+
+#if __GNUC__ > 3
+#define offsetof(type, member) __builtin_offsetof(type, member)
+#else
+#define offsetof(type, member) ((size_t)( (char *)&(((type *)0)->member) - (char *)0 ))
+#endif
+
+#endif
diff --git a/sysroot/include/stdlib.h b/sysroot/include/stdlib.h
new file mode 100644 (file)
index 0000000..e67b588
--- /dev/null
@@ -0,0 +1,179 @@
+#ifndef _STDLIB_H
+#define _STDLIB_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#if __cplusplus >= 201103L
+#define NULL nullptr
+#elif defined(__cplusplus)
+#define NULL 0L
+#else
+//#define NULL ((void*)0)
+#endif
+
+#define __NEED_size_t
+#define __NEED_wchar_t
+
+#include <bits/alltypes.h>
+
+int atoi (const char *);
+long atol (const char *);
+long long atoll (const char *);
+double atof (const char *);
+
+float strtof (const char *__restrict, char **__restrict);
+double strtod (const char *__restrict, char **__restrict);
+long double strtold (const char *__restrict, char **__restrict);
+
+long strtol (const char *__restrict, char **__restrict, int);
+unsigned long strtoul (const char *__restrict, char **__restrict, int);
+long long strtoll (const char *__restrict, char **__restrict, int);
+unsigned long long strtoull (const char *__restrict, char **__restrict, int);
+
+int rand (void);
+void srand (unsigned);
+
+void *malloc (size_t);
+void *calloc (size_t, size_t);
+void *realloc (void *, size_t);
+void free (void *);
+void *aligned_alloc(size_t, size_t);
+
+_Noreturn void abort (void);
+int atexit (void (*) (void));
+_Noreturn void exit (int);
+_Noreturn void _Exit (int);
+int at_quick_exit (void (*) (void));
+_Noreturn void quick_exit (int);
+
+char *getenv (const char *);
+
+int system (const char *);
+
+void *bsearch (const void *, const void *, size_t, size_t, int (*)(const void *, const void *));
+void qsort (void *, size_t, size_t, int (*)(const void *, const void *));
+
+int abs (int);
+long labs (long);
+long long llabs (long long);
+
+typedef struct { int quot, rem; } div_t;
+typedef struct { long quot, rem; } ldiv_t;
+typedef struct { long long quot, rem; } lldiv_t;
+
+div_t div (int, int);
+ldiv_t ldiv (long, long);
+lldiv_t lldiv (long long, long long);
+
+int mblen (const char *, size_t);
+int mbtowc (wchar_t *__restrict, const char *__restrict, size_t);
+int wctomb (char *, wchar_t);
+size_t mbstowcs (wchar_t *__restrict, const char *__restrict, size_t);
+size_t wcstombs (char *__restrict, const wchar_t *__restrict, size_t);
+
+#define EXIT_FAILURE 1
+#define EXIT_SUCCESS 0
+
+size_t __ctype_get_mb_cur_max(void);
+#define MB_CUR_MAX (__ctype_get_mb_cur_max())
+
+#define RAND_MAX (0x7fffffff)
+
+
+#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \
+ || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) \
+ || defined(_BSD_SOURCE)
+
+#define WNOHANG    1
+#define WUNTRACED  2
+
+#define WEXITSTATUS(s) (((s) & 0xff00) >> 8)
+#define WTERMSIG(s) ((s) & 0x7f)
+#define WSTOPSIG(s) WEXITSTATUS(s)
+#define WIFEXITED(s) (!WTERMSIG(s))
+#define WIFSTOPPED(s) ((short)((((s)&0xffff)*0x10001U)>>8) > 0x7f00)
+#define WIFSIGNALED(s) (((s)&0xffff)-1U < 0xffu)
+
+int posix_memalign (void **, size_t, size_t);
+int setenv (const char *, const char *, int);
+int unsetenv (const char *);
+int mkstemp (char *);
+int mkostemp (char *, int);
+char *mkdtemp (char *);
+int getsubopt (char **, char *const *, char **);
+int rand_r (unsigned *);
+
+#endif
+
+
+#if defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) \
+ || defined(_BSD_SOURCE)
+char *realpath (const char *__restrict, char *__restrict);
+long int random (void);
+void srandom (unsigned int);
+char *initstate (unsigned int, char *, size_t);
+char *setstate (char *);
+int putenv (char *);
+int posix_openpt (int);
+int grantpt (int);
+int unlockpt (int);
+char *ptsname (int);
+char *l64a (long);
+long a64l (const char *);
+void setkey (const char *);
+double drand48 (void);
+double erand48 (unsigned short [3]);
+long int lrand48 (void);
+long int nrand48 (unsigned short [3]);
+long mrand48 (void);
+long jrand48 (unsigned short [3]);
+void srand48 (long);
+unsigned short *seed48 (unsigned short [3]);
+void lcong48 (unsigned short [7]);
+#endif
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+#include <alloca.h>
+char *mktemp (char *);
+int mkstemps (char *, int);
+int mkostemps (char *, int, int);
+void *valloc (size_t);
+void *memalign(size_t, size_t);
+int getloadavg(double *, int);
+int clearenv(void);
+#define WCOREDUMP(s) ((s) & 0x80)
+#define WIFCONTINUED(s) ((s) == 0xffff)
+void *reallocarray (void *, size_t, size_t);
+void qsort_r (void *, size_t, size_t, int (*)(const void *, const void *, void *), void *);
+#endif
+
+#ifdef _GNU_SOURCE
+int ptsname_r(int, char *, size_t);
+char *ecvt(double, int, int *, int *);
+char *fcvt(double, int, int *, int *);
+char *gcvt(double, int, char *);
+char *secure_getenv(const char *);
+struct __locale_struct;
+float strtof_l(const char *__restrict, char **__restrict, struct __locale_struct *);
+double strtod_l(const char *__restrict, char **__restrict, struct __locale_struct *);
+long double strtold_l(const char *__restrict, char **__restrict, struct __locale_struct *);
+#endif
+
+#if defined(_LARGEFILE64_SOURCE)
+#define mkstemp64 mkstemp
+#define mkostemp64 mkostemp
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+#define mkstemps64 mkstemps
+#define mkostemps64 mkostemps
+#endif
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/sysroot/include/string.h b/sysroot/include/string.h
new file mode 100644 (file)
index 0000000..da38e56
--- /dev/null
@@ -0,0 +1,104 @@
+#ifndef        _STRING_H
+#define        _STRING_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <features.h>
+
+#if __cplusplus >= 201103L
+#define NULL nullptr
+#elif defined(__cplusplus)
+#define NULL 0L
+#else
+//#define NULL ((void*)0)
+#endif
+
+#define __NEED_size_t
+#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \
+ || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) \
+ || defined(_BSD_SOURCE)
+#define __NEED_locale_t
+#endif
+
+#include <bits/alltypes.h>
+
+void *memcpy (void *__restrict, const void *__restrict, size_t);
+void *memmove (void *, const void *, size_t);
+void *memset (void *, int, size_t);
+int memcmp (const void *, const void *, size_t);
+void *memchr (const void *, int, size_t);
+
+char *strcpy (char *__restrict, const char *__restrict);
+char *strncpy (char *__restrict, const char *__restrict, size_t);
+
+char *strcat (char *__restrict, const char *__restrict);
+char *strncat (char *__restrict, const char *__restrict, size_t);
+
+int strcmp (const char *, const char *);
+int strncmp (const char *, const char *, size_t);
+
+int strcoll (const char *, const char *);
+size_t strxfrm (char *__restrict, const char *__restrict, size_t);
+
+char *strchr (const char *, int);
+char *strrchr (const char *, int);
+
+size_t strcspn (const char *, const char *);
+size_t strspn (const char *, const char *);
+char *strpbrk (const char *, const char *);
+char *strstr (const char *, const char *);
+char *strtok (char *__restrict, const char *__restrict);
+
+size_t strlen (const char *);
+
+char *strerror (int);
+
+#if defined(_BSD_SOURCE) || defined(_GNU_SOURCE)
+#include <strings.h>
+#endif
+
+#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \
+ || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) \
+ || defined(_BSD_SOURCE)
+char *strtok_r (char *__restrict, const char *__restrict, char **__restrict);
+int strerror_r (int, char *, size_t);
+char *stpcpy(char *__restrict, const char *__restrict);
+char *stpncpy(char *__restrict, const char *__restrict, size_t);
+size_t strnlen (const char *, size_t);
+char *strdup (const char *);
+char *strndup (const char *, size_t);
+char *strsignal(int);
+char *strerror_l (int, locale_t);
+int strcoll_l (const char *, const char *, locale_t);
+size_t strxfrm_l (char *__restrict, const char *__restrict, size_t, locale_t);
+void *memmem(const void *, size_t, const void *, size_t);
+#endif
+
+#if defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) \
+ || defined(_BSD_SOURCE)
+void *memccpy (void *__restrict, const void *__restrict, int, size_t);
+#endif
+
+#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
+char *strsep(char **, const char *);
+size_t strlcat (char *, const char *, size_t);
+size_t strlcpy (char *, const char *, size_t);
+void explicit_bzero (void *, size_t);
+#endif
+
+#ifdef _GNU_SOURCE
+#define        strdupa(x)      strcpy(alloca(strlen(x)+1),x)
+int strverscmp (const char *, const char *);
+char *strchrnul(const char *, int);
+char *strcasestr(const char *, const char *);
+void *memrchr(const void *, int, size_t);
+void *mempcpy(void *, const void *, size_t);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
index 349657f06502d384a7b95d938029179e6ff20a68..abf945ec21696284232c6f1af222b0681e6ce142 100644 (file)
@@ -6,5 +6,4 @@ struct __builtin_va_list
 
        intptr_t  ireg;
        intptr_t  freg;
-       intptr_t  others;
 };