js: anonymous function & var init ok
authoryu.dongliang <18588496441@163.com>
Fri, 22 Aug 2025 09:11:39 +0000 (17:11 +0800)
committeryu.dongliang <18588496441@163.com>
Fri, 22 Aug 2025 09:11:39 +0000 (17:11 +0800)
15 files changed:
examples/js.html
js/core/scf_ast.c
js/core/scf_operator_handler_3ac.c
js/core/scf_variable.h
js/doc.c
js/parse/scf_dfa.c
js/parse/scf_dfa_call.c
js/parse/scf_dfa_expr.c
js/parse/scf_dfa_function_js.c
js/parse/scf_dfa_init_data.c
js/parse/scf_dfa_return.c
js/parse/scf_dfa_var.c
js/parse/scf_operator_handler_semantic.c
js/parse/scf_parse.c
js/parse/scf_parse.h

index 8716472fddf6f6674495ade368f22ab67a94377b..5811a5656e4a08d8fd80485c8dc546041dfd0548 100644 (file)
@@ -7,14 +7,12 @@
 <p>含有js的页面</p>
 
 <script>
-var a = {
-       x: 1.1,
-       f: function () {
-               document.write(a.x);
-       }
-};
 
-a.f();
+var a = function(x, y) {
+               return x + y;
+       }(1, 2);
+
+document.write(a);
 </script>
 
 </body>
index e3fd536811067bc618cb717e3a624320dec3c8ca..0b79c910dc4c9db3d549cff5b31f1297abd02b4b 100644 (file)
@@ -109,7 +109,7 @@ static int _find_function_by_name(scf_node_t* node, void* arg, scf_vector_t* vec
 
                scf_function_t* f = (scf_function_t*)node;
 
-               assert(!f->member_flag);
+               assert(f->js_flag || !f->member_flag);
 
                if (f->static_flag)
                        return 0;
index 5f3d29f77ecb38d332c2e7d3956b833bc543493d..c03304966a10fcd00930619a081e06c55297d602 100644 (file)
@@ -96,7 +96,7 @@ static int _scf_expr_calculate_internal(scf_ast_t* ast, scf_node_t* node, void*
                return h(ast, node->nodes, node->nb_nodes, d);
 
        } else {
-               if (!scf_type_is_assign(node->op->type) && SCF_OP_ADDRESS_OF != node->op->type) {
+               if (!scf_type_is_assign(node->op->type) && SCF_OP_ADDRESS_OF != node->op->type && SCF_OP_CREATE != node->op->type) {
 
                        for (i = node->nb_nodes - 1; i >= 0; i--) {
                                if (_scf_expr_calculate_internal(ast, node->nodes[i], d) < 0) {
@@ -1446,15 +1446,6 @@ static int _scf_op_create(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void
        int ret;
        int i;
 
-       for (i = 3; i < nb_nodes; i++) {
-
-               ret = _scf_expr_calculate_internal(ast, nodes[i], d);
-               if (ret < 0) {
-                       scf_loge("\n");
-                       return ret;
-               }
-       }
-
        nthis = parent->result_nodes->data[0];
        nerr  = parent->result_nodes->data[1];
 
@@ -1474,12 +1465,6 @@ static int _scf_op_create(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void
        nerr->split_flag   = 0;
        nerr->split_parent = NULL;
 
-       for (i = 2; i < nb_nodes; i++)
-               scf_node_add_child(nerr, nodes[i]);
-
-       for (i = 1; i < nb_nodes; i++)
-               nodes[i] = NULL;
-
        parent->nodes[0] = nerr;
        parent->nb_nodes = 1;
        nerr->parent     = parent;
@@ -1508,6 +1493,21 @@ static int _scf_op_create(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void
        jz  = scf_3ac_jmp_code(SCF_OP_3AC_JZ, NULL, NULL);
        scf_list_add_tail(d->_3ac_list_head, &jz->list);
 
+       for (i = 3; i < nb_nodes; i++) {
+
+               ret = _scf_expr_calculate_internal(ast, nodes[i], d);
+               if (ret < 0) {
+                       scf_loge("\n");
+                       return ret;
+               }
+       }
+
+       for (i = 2; i < nb_nodes; i++)
+               scf_node_add_child(nerr, nodes[i]);
+
+       for (i = 1; i < nb_nodes; i++)
+               nodes[i] = NULL;
+
        ret = _scf_3ac_code_N(d->_3ac_list_head, SCF_OP_CALL, nerr, nerr->nodes, nerr->nb_nodes);
        if (ret < 0) {
                scf_loge("\n");
index 1e4ae3d7c0732ec2fe0c939b97d1d9a48b2e9d8d..1d560a14b07a36439d1e59497d009026554eb89f 100644 (file)
@@ -28,6 +28,8 @@ struct scf_variable_s {
        int                                     nb_pointers; // Multiple pointer count
        scf_function_t*     func_ptr;
 
+       scf_type_t*         parent_type;
+
        scf_dimention_t*    dimentions;    // number of every dimention
        int                                     nb_dimentions; // total dimentions
        int                 dim_index;
index 849a9db5030549a26a284d0fe23541ae8a99d77e..0a437d6bc7f6b169e58f2ccad22fc7820134ce06 100644 (file)
--- a/js/doc.c
+++ b/js/doc.c
@@ -1,5 +1,9 @@
 #include"../js/lib/scf_capi.c"
 
+struct Object;
+
+int abc_html_write(Object* html, const char* s);
+
 struct Object
 {
        int       type;
@@ -72,6 +76,12 @@ struct Object
                return s;
        }
 
+       void write(Object* this, Object* obj)
+       {
+               char* s = obj.toString();
+               abc_html_write(this, s);
+       }
+
        Object* operator+(Object* this, Object* that)
        {
                Object* res = create Object(this->d + that->d);
@@ -103,22 +113,9 @@ struct Object
        }
 };
 
-struct HTML;
-
-int abc_html_write(HTML* html, const char* s);
-
-struct HTML
-{
-       void write(HTML* this, Object* obj)
-       {
-               char* s = obj.toString();
-               abc_html_write(this, s);
-       }
-};
-
-HTML* document = NULL;
+Object* document = NULL;
 
-void __js_main(HTML* this)
+void __js_main(Object* doc)
 {
-       document = this;
+       document = doc;
 }
index d8a1a93c12d6ae88071af9eec4c7a1c78257ed45..7d5045d6d4fbb5a970febfcbe75e4166e82ea1f7 100644 (file)
@@ -11,7 +11,7 @@ static scf_dfa_ops_t*  dfa_ops_array[] =
        NULL,
 };
 
-static int _scf_dfa_node_parse_word(scf_dfa_t* dfa, scf_dfa_node_t* node, scf_vector_t* words, void* data);
+static int _scf_dfa_node_parse_word(scf_dfa_t* dfa, scf_dfa_node_t* node, scf_vector_t* words, void* data, int pre_hook_flag);
 
 void scf_dfa_del_hook_by_name(scf_dfa_hook_t** pp, const char* name)
 {
@@ -261,13 +261,16 @@ static int _scf_dfa_childs_parse_word(scf_dfa_t* dfa, scf_dfa_node_t** childs, i
                scf_dfa_node_t* child = childs[i];
                scf_lex_word_t* w     = words->data[words->size - 1];
 
-               scf_logd("i: %d, nb_childs: %d, child: %s, w: %s\n", i, nb_childs, child->name, w->text->data);
+               scf_logi("i: %d, nb_childs: %d, child: %s, w: %s\n", i, nb_childs, child->name, w->text->data);
+
+               int pre_hook_flag = 0;
 
                scf_dfa_hook_t* hook = scf_dfa_find_hook(dfa, &(dfa->hooks[SCF_DFA_HOOK_PRE]), w);
                if (hook) {
                        // if pre hook is set, deliver the word to the proper hook node.
                        if (hook->node != child)
                                continue;
+                       pre_hook_flag = 1;
 
                        scf_logi("\033[32mpre hook: %s\033[0m\n", hook->node->name);
 
@@ -281,7 +284,7 @@ static int _scf_dfa_childs_parse_word(scf_dfa_t* dfa, scf_dfa_node_t** childs, i
                                continue;
                }
 
-               int ret = _scf_dfa_node_parse_word(dfa, child, words, data);
+               int ret = _scf_dfa_node_parse_word(dfa, child, words, data, pre_hook_flag);
 
                if (SCF_DFA_OK == ret)
                        return SCF_DFA_OK;
@@ -294,7 +297,7 @@ static int _scf_dfa_childs_parse_word(scf_dfa_t* dfa, scf_dfa_node_t** childs, i
        return SCF_DFA_NEXT_SYNTAX;
 }
 
-static int _scf_dfa_node_parse_word(scf_dfa_t* dfa, scf_dfa_node_t* node, scf_vector_t* words, void* data)
+static int _scf_dfa_node_parse_word(scf_dfa_t* dfa, scf_dfa_node_t* node, scf_vector_t* words, void* data, int pre_hook_flag)
 {
        int             ret = SCF_DFA_NEXT_WORD;
        scf_lex_word_t* w   = words->data[words->size - 1];
@@ -332,57 +335,58 @@ static int _scf_dfa_node_parse_word(scf_dfa_t* dfa, scf_dfa_node_t* node, scf_ve
        printf("\n");
 #endif
 
-       scf_dfa_hook_t* hook = scf_dfa_find_hook(dfa, &(dfa->hooks[SCF_DFA_HOOK_POST]), w);
-       if (hook) {
-               scf_dfa_node_t* hook_node = hook->node;
+       if (!pre_hook_flag) {
+               scf_dfa_hook_t* hook = scf_dfa_find_hook(dfa, &(dfa->hooks[SCF_DFA_HOOK_POST]), w);
+               if (hook) {
+                       scf_dfa_node_t* hook_node = hook->node;
 
-               scf_dfa_clear_hooks(&(dfa->hooks[SCF_DFA_HOOK_POST]), hook->next);
-               hook = NULL;
+                       scf_dfa_clear_hooks(&(dfa->hooks[SCF_DFA_HOOK_POST]), hook->next);
+                       hook = NULL;
 
-               scf_logi("\033[32m post hook: %s->action()\033[0m\n", hook_node->name);
+                       scf_logi("\033[32m post hook: %s->action()\033[0m\n", hook_node->name);
 
-               if (hook_node != node && hook_node->action) {
+                       if (hook_node != node && hook_node->action) {
 
-                       ret = hook_node->action(dfa, words, data);
+                               ret = hook_node->action(dfa, words, data);
 
-                       if (SCF_DFA_SWITCH_TO == ret) {
-                               scf_logi("\033[32m post hook: switch to %s->%s\033[0m\n", node->name, hook_node->name);
+                               if (SCF_DFA_SWITCH_TO == ret) {
+                                       scf_logi("\033[32m post hook: switch to %s->%s\033[0m\n", node->name, hook_node->name);
 
-                               node = hook_node;
-                               ret = SCF_DFA_NEXT_WORD;
+                                       node = hook_node;
+                                       ret = SCF_DFA_NEXT_WORD;
+                               }
                        }
                }
-       }
 
-       if (SCF_DFA_OK == ret) {
+               if (SCF_DFA_OK == ret) {
+                       scf_dfa_hook_t** pp = &(dfa->hooks[SCF_DFA_HOOK_END]);
 
-               scf_dfa_hook_t** pp = &(dfa->hooks[SCF_DFA_HOOK_END]);
+                       while (*pp) {
+                               scf_dfa_hook_t* hook = *pp;
+                               scf_dfa_node_t* hook_node = hook->node;
 
-               while (*pp) {
-                       scf_dfa_hook_t* hook = *pp;
-                       scf_dfa_node_t* hook_node = hook->node;
+                               *pp = hook->next;
+                               free(hook);
+                               hook = NULL;
 
-                       *pp = hook->next;
-                       free(hook);
-                       hook = NULL;
-
-                       scf_logi("\033[34m end hook: %s->action()\033[0m\n", hook_node->name);
+                               scf_logi("\033[34m end hook: %s->action()\033[0m\n", hook_node->name);
 
-                       if (!hook_node->action)
-                               continue;
+                               if (!hook_node->action)
+                                       continue;
 
-                       ret = hook_node->action(dfa, words, data);
+                               ret = hook_node->action(dfa, words, data);
 
-                       if (SCF_DFA_OK == ret)
-                               continue;
+                               if (SCF_DFA_OK == ret)
+                                       continue;
 
-                       if (SCF_DFA_SWITCH_TO == ret) {
-                               scf_logi("\033[34m end hook: switch to %s->%s\033[0m\n\n", node->name, hook_node->name);
+                               if (SCF_DFA_SWITCH_TO == ret) {
+                                       scf_logi("\033[34m end hook: switch to %s->%s\033[0m\n\n", node->name, hook_node->name);
 
-                               node = hook_node;
-                               ret  = SCF_DFA_NEXT_WORD;
+                                       node = hook_node;
+                                       ret  = SCF_DFA_NEXT_WORD;
+                               }
+                               break;
                        }
-                       break;
                }
        }
 
index 2b06842c7acedaa86bc28cd6725d1e53a07692ce..714a1ef550def8f617b8892b64000e7dd043f801 100644 (file)
@@ -79,6 +79,10 @@ static int _call_action_lp(scf_dfa_t* dfa, scf_vector_t* words, void* data)
                        var_pf->const_flag = 1;
                        var_pf->const_literal_flag = 1;
 
+                       node_pf = scf_node_alloc(NULL, var_pf->type, var_pf);
+
+                       scf_variable_free(var_pf);
+                       var_pf = NULL;
                } else {
                        ret = scf_ast_find_variable(&var_pf, parse->ast, id->identity->text->data);
                        if (ret < 0)
@@ -93,9 +97,23 @@ static int _call_action_lp(scf_dfa_t* dfa, scf_vector_t* words, void* data)
                                scf_loge("invalid function ptr\n");
                                return SCF_DFA_ERROR;
                        }
+
+                       f = var_pf->func_ptr;
+
+                       if (f->js_flag) {
+                               scf_variable_t* v2 = scf_variable_clone(var_pf);
+                               if (!v2)
+                                       return -ENOMEM;
+
+                               scf_loge("f: %s\n", f->node.w->text->data);
+                               node_pf = scf_node_alloc(NULL, v2->type, v2);
+
+                               scf_variable_free(v2);
+                               v2 = NULL;
+                       } else
+                               node_pf = scf_node_alloc(NULL, var_pf->type, var_pf);
                }
 
-               node_pf = scf_node_alloc(NULL, var_pf->type, var_pf);
                if (!node_pf) {
                        scf_loge("node alloc failed\n");
                        return SCF_DFA_ERROR;
@@ -106,8 +124,8 @@ static int _call_action_lp(scf_dfa_t* dfa, scf_vector_t* words, void* data)
                id = NULL;
        } else {
                // f()(), function f should return a function pointer
-               scf_loge("\n");
-               return SCF_DFA_ERROR;
+               scf_logw("\n");
+//             return SCF_DFA_ERROR;
        }
 
        node_call = scf_node_alloc(w1, SCF_OP_CALL, NULL);
@@ -123,8 +141,6 @@ static int _call_action_lp(scf_dfa_t* dfa, scf_vector_t* words, void* data)
                return SCF_DFA_ERROR;
        }
 
-       scf_logd("d->expr: %p\n", d->expr);
-
        cd->func           = node_pf;
        cd->call           = node_call;
        cd->parent_expr    = d->expr;
@@ -140,6 +156,92 @@ static int _call_action_lp(scf_dfa_t* dfa, scf_vector_t* words, void* data)
        return SCF_DFA_NEXT_WORD;
 }
 
+static int _call_add_obj(scf_ast_t* ast, scf_lex_word_t* w, scf_node_t* call, scf_expr_t* e, scf_type_t* Object)
+{
+       scf_variable_t*  v = NULL;
+       scf_expr_t*      e2;
+       scf_node_t*      tmp0;
+       scf_node_t*      tmp1;
+       scf_node_t*      assign;
+
+       int ret = scf_expr_calculate(ast, e, &v);
+       if (ret < 0)
+               return ret;
+
+       if (v->type == Object->type) {
+               scf_variable_free(v);
+               return 0;
+       }
+
+       scf_variable_free(v);
+
+       v = SCF_VAR_ALLOC_BY_TYPE(w, Object, 0, 1, NULL);
+       if (!v)
+               return -ENOMEM;
+
+       tmp0 = scf_node_alloc(NULL, v->type, v);
+       if (!tmp0) {
+               scf_variable_free(v);
+               return -ENOMEM;
+       }
+
+       tmp1 = scf_node_alloc(NULL, v->type, v);
+       scf_variable_free(v);
+       v = NULL;
+       if (!tmp1) {
+               scf_node_free(tmp0);
+               return -ENOMEM;
+       }
+
+       assign = scf_node_alloc(w, SCF_OP_ASSIGN, NULL);
+       if (!assign) {
+               scf_node_free(tmp0);
+               scf_node_free(tmp1);
+               return -ENOMEM;
+       }
+
+       ret = scf_node_add_child(assign, tmp0);
+       if (ret < 0) {
+               scf_node_free(assign);
+               scf_node_free(tmp0);
+               scf_node_free(tmp1);
+               return ret;
+       }
+       tmp0 = NULL;
+
+       ret = scf_node_add_child(assign, e->nodes[0]);
+       if (ret < 0) {
+               scf_node_free(assign);
+               scf_node_free(tmp1);
+               return ret;
+       }
+       e->nodes[0]  = tmp1;
+       tmp1->parent = e;
+       tmp1         = NULL;
+
+       e2 = scf_expr_alloc();
+       if (!e2) {
+               scf_node_free(assign);
+               return -ENOMEM;
+       }
+
+       ret = scf_node_add_child(e2, assign);
+       if (ret < 0) {
+               scf_expr_free(e2);
+               scf_node_free(assign);
+               return ret;
+       }
+       assign = NULL;
+
+       ret = scf_node_add_child((scf_node_t*)ast->current_block, e2);
+       if (ret < 0) {
+               scf_expr_free(e2);
+               return ret;
+       }
+
+       return 0;
+}
+
 static int _call_action_rp(scf_dfa_t* dfa, scf_vector_t* words, void* data)
 {
        if (words->size < 2) {
@@ -176,16 +278,49 @@ static int _call_action_rp(scf_dfa_t* dfa, scf_vector_t* words, void* data)
        scf_stack_pop(s);
 
        if (cd->parent_expr) {
-               scf_expr_add_node(cd->parent_expr, cd->func);
+               if (cd->func)
+                       scf_expr_add_node(cd->parent_expr, cd->func);
+
                scf_expr_add_node(cd->parent_expr, cd->call);
        } else {
                scf_node_add_child(cd->call, cd->func);
        }
 
+       scf_variable_t*  r;
+       scf_function_t*  f;
+       scf_expr_t*      e;
+       scf_type_t*      t  = NULL;
+       scf_node_t*      pf = cd->call->nodes[0];
+
+       while (SCF_OP_EXPR == pf->type)
+               pf = pf->nodes[0];
+
+       if (SCF_OP_POINTER == pf->type)
+               pf = pf->nodes[1];
+
+       assert(SCF_FUNCTION_PTR == pf->type);
+
+       f = pf->var->func_ptr;
+
+       int ret = scf_ast_find_type(&t, parse->ast, "Object");
+       if (ret < 0)
+               return ret;
+
+       scf_logw("f: %s, f->js_flag: %d\n", f->node.w->text->data, f->js_flag);
+
        if (cd->argv) {
                int i;
-               for (i = 0; i < cd->argv->size; i++)
-                       scf_node_add_child(cd->call, cd->argv->data[i]);
+               for (i = 0; i < cd->argv->size; i++) {
+                       e  =        cd->argv->data[i];
+
+                       if (f->js_flag) {
+                               ret = _call_add_obj(parse->ast, w, cd->call, e, t);
+                               if (ret < 0)
+                                       return ret;
+                       }
+
+                       scf_node_add_child(cd->call, e);
+               }
 
                scf_vector_free(cd->argv);
                cd->argv = NULL;
@@ -193,6 +328,12 @@ static int _call_action_rp(scf_dfa_t* dfa, scf_vector_t* words, void* data)
 
        // the last arg
        if (d->expr) {
+               if (f->js_flag) {
+                       ret = _call_add_obj(parse->ast, w, cd->call, d->expr, t);
+                       if (ret < 0)
+                               return ret;
+               }
+
                scf_node_add_child(cd->call, d->expr);
                d->expr = NULL;
        }
@@ -202,9 +343,7 @@ static int _call_action_rp(scf_dfa_t* dfa, scf_vector_t* words, void* data)
        else
                d->expr = cd->call;
 
-       d->expr_local_flag--;
-
-       scf_logd("d->expr: %p\n", d->expr);
+       assert(--d->expr_local_flag >= 0);
 
        free(cd);
        cd = NULL;
index 419a28ba442f3c83598d1474aa8cee0b7d69cffc..e05c1bf699c18f192207beaf3ba55ab1738056a2 100644 (file)
@@ -21,6 +21,7 @@ static int _expr_is_expr(scf_dfa_t* dfa, void* word)
        scf_lex_word_t* w = word;
 
        if (SCF_LEX_WORD_SEMICOLON == w->type
+                       || SCF_LEX_WORD_KEY_FUNC == w->type
                        || scf_lex_is_operator(w)
                        || scf_lex_is_const(w)
                        || scf_lex_is_identity(w))
@@ -126,6 +127,7 @@ int _expr_add_var(scf_parse_t* parse, dfa_data_t* d)
 
        if (md->current_var
                        && md->current_var->js_type >= 0
+                       && SCF_FUNCTION_PTR != var->type
                        && var->member_flag) {
                scf_logi("md->current_var: %s, var: %s, member_flag: %d, line: %d, pos: %d\n",
                                md->current_var->w->text->data, var->w->text->data, var->member_flag, var->w->line, var->w->pos);
@@ -188,6 +190,7 @@ int _expr_add_var(scf_parse_t* parse, dfa_data_t* d)
                assert(md->current_struct);
        }
        md->current_var = var;
+       d->js_var       = var;
 
        free(id);
        id = NULL;
@@ -994,8 +997,10 @@ static int _dfa_init_syntax_expr(scf_dfa_t* dfa)
        SCF_DFA_GET_MODULE_NODE(dfa, va_arg,   arg,         va_arg);
        SCF_DFA_GET_MODULE_NODE(dfa, va_arg,   rp,          va_rp);
 
-       SCF_DFA_GET_MODULE_NODE(dfa, container, container,  container);
-       SCF_DFA_GET_MODULE_NODE(dfa, container, rp,         container_rp);
+       SCF_DFA_GET_MODULE_NODE(dfa, container,   container,  container);
+       SCF_DFA_GET_MODULE_NODE(dfa, container,   rp,         container_rp);
+       SCF_DFA_GET_MODULE_NODE(dfa, function_js, func,       js_func);
+       SCF_DFA_GET_MODULE_NODE(dfa, function_js, end,        js_func_end);
 
        // add expr to syntaxes
        scf_vector_add(dfa->syntaxes, expr);
@@ -1010,6 +1015,10 @@ static int _dfa_init_syntax_expr(scf_dfa_t* dfa)
        scf_dfa_node_add_child(expr,       lp);
        scf_dfa_node_add_child(expr,       semicolon);
 
+       // function() {}
+       scf_dfa_node_add_child(expr,         js_func);
+       scf_dfa_node_add_child(js_func_end,  rp);
+
        // container(ptr, type, member)
        scf_dfa_node_add_child(expr,         container);
        scf_dfa_node_add_child(container_rp, rp);
index ed8c05763cd80b54752654d85308fdb334d231b4..5cf7336fe890fa62836475fed29b120046a2c384 100644 (file)
@@ -5,8 +5,9 @@
 extern scf_dfa_module_t dfa_module_function_js;
 
 typedef struct {
-
        scf_block_t*     parent_block;
+       scf_expr_t*      parent_expr;
+       scf_variable_t*  parent_var;
 
 } dfa_fun_data_t;
 
@@ -18,26 +19,31 @@ int _function_js_add_function(scf_dfa_t* dfa, scf_lex_word_t* w, dfa_data_t* d)
 
        scf_function_t* f;
        scf_variable_t* v;
-       scf_block_t*    b;
        scf_type_t*     t = NULL;
 
        int ret = scf_ast_find_type(&t, ast, "Object");
        if (ret < 0)
                return ret;
 
-       b = ast->current_block;
-       while (b) {
-               if (b->node.type >= SCF_STRUCT)
-                       break;
-               b = (scf_block_t*)b->node.parent;
-       }
-
        f = scf_function_alloc(w);
        if (!f)
                return SCF_DFA_ERROR;
-       f->member_flag = !!b;
+       f->member_flag = 1;
        f->js_flag     = 1;
 
+       if (SCF_LEX_WORD_KEY_FUNC == w->type) {
+               char buf[128];
+               int  len = snprintf(buf, sizeof(buf) - 1, "_js%d", ast->nb_functions);
+
+               ret = scf_string_cat_cstr_len(f->node.w->text, buf, len);
+               if (ret < 0) {
+                       scf_function_free(f);
+                       return ret;
+               }
+
+               ast->nb_functions++;
+       }
+
        scf_logi("function: %s,line:%d, member_flag: %d\n", f->node.w->text->data, f->node.w->line, f->member_flag);
 
        v = SCF_VAR_ALLOC_BY_TYPE(w, t, 0, 1, NULL);
@@ -141,7 +147,10 @@ static int _function_js_action_lp(scf_dfa_t* dfa, scf_vector_t* words, void* dat
 
        assert(!d->current_node);
 
-       d->current_var = NULL;
+       fd->parent_expr = d->expr;
+       fd->parent_var  = d->js_var;
+       d->js_var       = NULL;
+       d->expr         = NULL;
 
        if (_function_js_add_function(dfa, w, d) < 0)
                return SCF_DFA_ERROR;
@@ -152,25 +161,24 @@ static int _function_js_action_lp(scf_dfa_t* dfa, scf_vector_t* words, void* dat
        d->argc = 0;
        d->nb_lps++;
 
-       if (d->current_function->member_flag) {
-               this = scf_lex_word_alloc(w->file, 0, 0, SCF_LEX_WORD_ID);
-               if (!this)
-                       return SCF_DFA_ERROR;
-
-               this->text = scf_string_cstr("this");
-               if (!this->text) {
-                       scf_lex_word_free(this);
-                       return SCF_DFA_ERROR;
-               }
-
-               int ret = _function_js_add_arg(parse->ast, this, d);
+       // add 'this'
+       this = scf_lex_word_alloc(w->file, 0, 0, SCF_LEX_WORD_ID);
+       if (!this)
+               return SCF_DFA_ERROR;
 
+       this->text = scf_string_cstr("this");
+       if (!this->text) {
                scf_lex_word_free(this);
-               this = NULL;
-               if (ret < 0)
-                       return SCF_DFA_ERROR;
+               return SCF_DFA_ERROR;
        }
 
+       int ret = _function_js_add_arg(parse->ast, this, d);
+
+       scf_lex_word_free(this);
+       this = NULL;
+       if (ret < 0)
+               return SCF_DFA_ERROR;
+
        return SCF_DFA_NEXT_WORD;
 }
 
@@ -240,14 +248,76 @@ static int _function_js_action_end(scf_dfa_t* dfa, scf_vector_t* words, void* da
        scf_parse_t*     parse = dfa->priv;
        dfa_data_t*      d     = data;
        scf_lex_word_t*  w     = words->data[words->size - 1];
+       scf_lex_word_t*  h     = NULL;
        dfa_fun_data_t*  fd    = d->module_datas[dfa_module_function_js.index];
+       scf_function_t*  f     = d->current_function;
+       scf_type_t*      t;
 
        parse->ast->current_block = (scf_block_t*)(fd->parent_block);
 
-       if (d->current_function->node.nb_nodes > 0)
-               d->current_function->node.define_flag = 1;
+       if (f->node.nb_nodes > 0)
+               f->node.define_flag = 1;
+
+       int call_flag = 0;
+       while (w = dfa->ops->pop_word(dfa)) {
+               w->next = h;
+               h = w;
+
+               if (SCF_LEX_WORD_RP != w->type) {
+                       if (SCF_LEX_WORD_LP == w->type)
+                               call_flag = 1;
+                       break;
+               }
+       }
+
+       while (h) {
+               w = h;
+               h = h->next;
+               dfa->ops->push_word(dfa, w);
+       }
+
+       if (call_flag) {
+               w = scf_lex_word_clone(f->node.w);
+               if (!w)
+                       return -ENOMEM;
+               w->type = SCF_LEX_WORD_ID;
+
+               dfa->ops->push_word(dfa, w);
+
+               d->expr         = fd->parent_expr;
+               fd->parent_expr = NULL;
+
+       } else if (fd->parent_expr) {
+               if (!fd->parent_var) {
+                       scf_loge("\n");
+                       return SCF_DFA_ERROR;
+               }
+
+               if (SCF_FUNCTION_PTR != fd->parent_var->type) {
+                       scf_loge("\n");
+                       return SCF_DFA_ERROR;
+               }
+
+               fd->parent_var->func_ptr = f;
+
+               if (fd->parent_var->member_flag) {
+                       f->member_flag = 1;
+
+                       scf_list_del(&f->list);
+                       scf_node_del_child((scf_node_t*)fd->parent_block, (scf_node_t*)f);
+
+                       t = fd->parent_var->parent_type;
+
+                       scf_scope_push_function(t->scope, f);
+                       scf_node_add_child((scf_node_t*)t, (scf_node_t*)f);
+               }
+
+               scf_expr_free(fd->parent_expr);
+       }
 
        fd->parent_block = NULL;
+       fd->parent_expr  = NULL;
+       fd->parent_var   = NULL;
 
        if (d->current_function->member_flag) {
 
@@ -258,6 +328,9 @@ static int _function_js_action_end(scf_dfa_t* dfa, scf_vector_t* words, void* da
        d->nb_lps = 0;
        d->nb_rps = 0;
 
+       if (call_flag)
+               return SCF_DFA_NEXT_WORD;
+
        return SCF_DFA_OK;
 }
 
index 88d7ff10af5f64243cd030f98078877e35c48844..67b9d8fa314e318a99ed6cbf789a99192b851261 100644 (file)
@@ -292,29 +292,42 @@ static int _data_action_func_end(scf_dfa_t* dfa, scf_vector_t* words, void* data
        dfa_data_t*          d     = data;
        init_module_data_t*  md    = d->module_datas[dfa_module_init_data.index];
        scf_lex_word_t*      w;
+       scf_variable_t*      v;
        scf_variable_t*      obj   = scf_stack_top(md->init_objs);
-       scf_type_t*          t;
+       scf_type_t*          s     = NULL;
+       scf_type_t*          t     = scf_block_find_type_type(ast->current_block, SCF_FUNCTION_PTR);
 
        d->expr_local_flag = 1;
        d->current_var     = md->current_var;
 
        assert(SCF_VAR_VAR != obj->type);
 
-       int ret = scf_ast_find_type_type(&t, ast, obj->type);
+       int ret = scf_ast_find_type_type(&s, ast, obj->type);
        if (ret < 0)
                return ret;
 
        w = md->current_index[md->current_dim].w;
        assert(w);
-       md->current_index[md->current_dim].w = NULL;
 
-       scf_logi("add member '%s()' to '%s_%d_%d'\n", w->text->data, obj->w->text->data, obj->w->line, obj->w->pos);
+       scf_logi("add member '%s()' to '%s_%d_%d, d->expr: %p'\n", w->text->data, obj->w->text->data, obj->w->line, obj->w->pos, d->expr);
 
        assert(d->current_function);
 
-       ret = scf_string_copy(d->current_function->node.w->text, w->text);
-       if (ret < 0)
-               return ret;
+       v = SCF_VAR_ALLOC_BY_TYPE(w, t, 1, 1, d->current_function);
+       if (!v)
+               return -ENOMEM;
+       v->member_flag        = 1;
+       v->const_literal_flag = 1;
+       v->parent_type        = s;
+
+       scf_scope_push_var(s->scope, v);
+
+       w = dfa->ops->pop_word(dfa);
+       dfa->ops->push_word(dfa, w); // only check if next word is ','.
+       if (SCF_LEX_WORD_COMMA != w->type)
+               md->current_index[md->current_dim].i++;
+
+       md->current_index[md->current_dim].w = NULL;
 
        d->current_function = NULL;
        return SCF_DFA_SWITCH_TO;
@@ -717,6 +730,7 @@ static int _dfa_init_syntax_init_data(scf_dfa_t* dfa)
        // init member function()
        scf_dfa_node_add_child(colon,     func);
        scf_dfa_node_add_child(func,      func_js);
+       scf_dfa_node_add_child(func_end,  comma);
        scf_dfa_node_add_child(func_end,  member);
        scf_dfa_node_add_child(func_end,  rb);
 
index 73228c75efcefbe8e8749e7a5ad2761df6a0464a..3a2b68558ae27b8168acae05422a35ea911982d9 100644 (file)
@@ -28,7 +28,7 @@ static int _return_action_return(scf_dfa_t* dfa, scf_vector_t* words, void* data
                scf_node_add_child((scf_node_t*)parse->ast->current_block, _return);
 
        d->current_return  = _return;
-       d->expr_local_flag = 1;
+       d->expr_local_flag++;
 
        SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "return_semicolon"), SCF_DFA_HOOK_POST);
        SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "return_comma"),     SCF_DFA_HOOK_POST);
@@ -61,7 +61,7 @@ static int _return_action_semicolon(scf_dfa_t* dfa, scf_vector_t* words, void* d
                d->expr = NULL;
        }
 
-       d->expr_local_flag = 0;
+       assert(--d->expr_local_flag >= 0);
 
        if (d->current_return->nb_nodes > 4) {
                scf_loge("return values must NOT more than 4!\n");
index 45b7608ebbfdc16c8735214964e5fa6a4c5a79c7..2ba29aa1b2f456dc45a3bd67d1dce231031ee488 100644 (file)
@@ -173,7 +173,7 @@ static int _var_init_expr(scf_dfa_t* dfa, dfa_data_t* d, scf_vector_t* words, in
                scf_loge("\n");
                return SCF_DFA_ERROR;
        }
-       d->expr_local_flag--;
+       assert(--d->expr_local_flag >= 0);
 
        assert(d->current_var);
 
index 7f7294b7eec55e055193f41e9e1aaf606072325b..03317ce4ec6384be655724ae5005d6df28d25dee 100644 (file)
@@ -1571,6 +1571,7 @@ static int _scf_op_semantic_call(scf_ast_t* ast, scf_node_t** nodes, int nb_node
        scf_variable_t**    pret   = d->pret;
        scf_variable_t*     v0;
        scf_variable_t*     v1;
+       scf_variable_t*     v;
        scf_function_t*     f;
        scf_node_t*         p;
        scf_node_t*         parent = nodes[0]->parent;
@@ -1600,33 +1601,52 @@ static int _scf_op_semantic_call(scf_ast_t* ast, scf_node_t** nodes, int nb_node
                while (p && SCF_OP_EXPR == p->type)
                        p = p->nodes[0];
 
-               if (!p || SCF_OP_POINTER != p->type || 2 != p->nb_nodes) {
-                       scf_loge("\n");
-                       return -1;
-               }
+               switch (p->type) {
+                       case SCF_OP_POINTER:
+                               assert(2 == p->nb_nodes);
+
+                               this = p->nodes[0];
+                               break;
+
+                       case SCF_FUNCTION_PTR:
+                               ret = scf_ast_find_variable(&v, ast, "document");
+                               if (ret < 0)
+                                       return ret;
+
+                               this = scf_node_alloc(NULL, v->type, v);
+                               if (!this)
+                                       return -ENOMEM;
 
-               this = p->nodes[0];
+                               scf_logi("this: %p\n", this);
+                               break;
+                       default:
+                               scf_loge("\n");
+                               return -1;
+                               break;
+               };
 
                scf_node_add_child(parent, this);
 
                int i;
-               for (i = 1; i < nb_nodes; i++)
-                       nodes[i + 1] = nodes[i];
-               nodes[1] = this;
-
-               for (i = 0; i < p->parent->nb_nodes; i++) {
-                       if (p->parent->nodes[i] == p) {
-                               p->parent->nodes[i]  = p->nodes[1];
-                               p->nodes[1]->parent  = p->parent;
-                               break;
+               for (i = parent->nb_nodes - 2; i >= 1; i--)
+                       parent->nodes[i + 1] = parent->nodes[i];
+               parent->nodes[1] = this;
+
+               if (SCF_OP_POINTER == p->type) {
+                       for (i = 0; i < p->parent->nb_nodes; i++) {
+                               if (p->parent->nodes[i] == p) {
+                                       p->parent->nodes[i]  = p->nodes[1];
+                                       p->nodes[1]->parent  = p->parent;
+                                       break;
+                               }
                        }
-               }
 
-               p->nodes[0] = NULL;
-               p->nodes[1] = NULL;
+                       p->nodes[0] = NULL;
+                       p->nodes[1] = NULL;
 
-               scf_node_free(p);
-               p = NULL;
+                       scf_node_free(p);
+                       p = NULL;
+               }
 
                nb_nodes++;
        }
@@ -1643,11 +1663,13 @@ static int _scf_op_semantic_call(scf_ast_t* ast, scf_node_t** nodes, int nb_node
                return -1;
        }
 
+       scf_logi("f: %s, f->argv->size: %d, nb_nodes: %d\n", f->node.w->text->data, f->argv->size, nb_nodes);
+
        int i;
        for (i = 0; i < f->argv->size; i++) {
                v0 =        f->argv->data[i];
 
-               v1 = _scf_operand_get(nodes[i + 1]);
+               v1 = _scf_operand_get(parent->nodes[i + 1]);
 
                if (SCF_VAR_VOID == v1->type && 0 == v1->nb_pointers) {
                        scf_loge("void var should be a pointer\n");
@@ -1663,7 +1685,7 @@ static int _scf_op_semantic_call(scf_ast_t* ast, scf_node_t** nodes, int nb_node
                        return -1;
                }
 
-               ret = _semantic_add_type_cast(ast, &nodes[i + 1], v0, nodes[i + 1]);
+               ret = _semantic_add_type_cast(ast, &(parent->nodes[i + 1]), v0, parent->nodes[i + 1]);
                if (ret < 0) {
                        scf_loge("\n");
                        return -1;
index a56cef79030a4802b6d3a5c15d72073d66756155..436312d62a0147e25487c102d3a1b398f87663ad 100644 (file)
@@ -1902,7 +1902,7 @@ int scf_parse_compile_functions(scf_parse_t* parse, scf_vector_t* functions)
                }
 
                assert(scf_list_empty(&h));
-//             scf_basic_block_print_list(&f->basic_block_list_head);
+               scf_basic_block_print_list(&f->basic_block_list_head);
        }
 
        int ret = scf_optimize(parse->ast, functions);
index aa89b4c976c83c02aeca8bb73461d592dd7c89b1..5f78ea99702fb522dd8904557ca19ad5c1c3b06d 100644 (file)
@@ -74,6 +74,8 @@ struct dfa_data_s {
        scf_variable_t*      current_var;
        scf_lex_word_t*      current_var_w;
 
+       scf_variable_t*      js_var;
+
        int                  nb_sizeofs;
        int                  nb_containers;