js: use function object to call() master
authoryu.dongliang <18588496441@163.com>
Sat, 23 Aug 2025 16:17:59 +0000 (00:17 +0800)
committeryu.dongliang <18588496441@163.com>
Sat, 23 Aug 2025 16:17:59 +0000 (00:17 +0800)
examples/js.html
js/core/scf_type_cast.c
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_operator_handler_semantic.c
js/parse/scf_parse.h

index 5811a5656e4a08d8fd80485c8dc546041dfd0548..146d3e43b65fa84e3bfdb28c59e2bf3aca90184a 100644 (file)
@@ -10,9 +10,9 @@
 
 var a = function(x, y) {
                return x + y;
-       }(1, 2);
+       };
 
-document.write(a);
+document.write(a(1, 2));
 </script>
 
 </body>
index 15e0c73715cfd6f81a30932d463f79248214de6c..7f103d9d83a408b821825511d2327b517eab5f23 100644 (file)
@@ -176,7 +176,7 @@ failed:
        dst_type = scf_variable_type_name(ast, dst);
        src_type = scf_variable_type_name(ast, src);
 
-       scf_loge("type cast '%s -> %s' with different type: from '%s' to '%s', file: %s, line: %d\n",
+       scf_logw("type cast '%s -> %s' with different type: from '%s' to '%s', file: %s, line: %d\n",
                        src->w->text->data, dst->w->text->data,
                        src_type->data, dst_type->data, src->w->file->data, src->w->line);
 
index 0a437d6bc7f6b169e58f2ccad22fc7820134ce06..171108871c55c47927f2a5207aebc9c1fd56da03 100644 (file)
--- a/js/doc.c
+++ b/js/doc.c
@@ -20,6 +20,17 @@ struct Object
                return 0;
        }
 
+       int __init(Object* this, int64_t d)
+       {
+               this->d = d;
+               return 0;
+       }
+
+       int __init(Object* this, void* p)
+       {
+               return 0;
+       }
+
        int __init(Object* this, const char* name, int n_members)
        {
                printf("this: %p, name: %s\n", this, name);
index 7d5045d6d4fbb5a970febfcbe75e4166e82ea1f7..790cbfb1ea19165b2f77369f4fefc2b88c155370 100644 (file)
@@ -261,7 +261,7 @@ 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_logi("i: %d, nb_childs: %d, child: %s, w: %s\n", i, nb_childs, child->name, w->text->data);
+               scf_logd("i: %d, nb_childs: %d, child: %s, w: %s\n", i, nb_childs, child->name, w->text->data);
 
                int pre_hook_flag = 0;
 
index 714a1ef550def8f617b8892b64000e7dd043f801..18a26add0b74e183ededf798a5600cab2f3cd2b7 100644 (file)
@@ -40,6 +40,7 @@ static int _call_action_lp_stat(scf_dfa_t* dfa, scf_vector_t* words, void* data)
 static int _call_action_lp(scf_dfa_t* dfa, scf_vector_t* words, void* data)
 {
        scf_parse_t*      parse     = dfa->priv;
+       scf_ast_t*        ast       = parse->ast;
        dfa_data_t*       d         = data;
        scf_lex_word_t*   w1        = words->data[words->size - 1];
        scf_stack_t*      s         = d->module_datas[dfa_module_call.index];
@@ -49,11 +50,12 @@ static int _call_action_lp(scf_dfa_t* dfa, scf_vector_t* words, void* data)
        scf_variable_t*   var_pf    = NULL;
        scf_node_t*       node_pf   = NULL;
        scf_type_t*       pt        = NULL;
+       scf_type_t*       Object    = NULL;
 
        scf_node_t*       node_call = NULL;
        scf_operator_t*   op        = scf_find_base_operator_by_type(SCF_OP_CALL);
 
-       if (scf_ast_find_type_type(&pt, parse->ast, SCF_FUNCTION_PTR) < 0)
+       if (scf_ast_find_type_type(&pt, ast, SCF_FUNCTION_PTR) < 0)
                return SCF_DFA_ERROR;
 
        assert(pt);
@@ -62,8 +64,8 @@ static int _call_action_lp(scf_dfa_t* dfa, scf_vector_t* words, void* data)
        dfa_identity_t* id = scf_stack_top(d->current_identities);
        if (id && id->identity) {
 
-               scf_logi("parse->ast->current_block: %p, js_type: %d\n", parse->ast->current_block, parse->ast->current_block->node.type);
-               int ret = scf_ast_find_function(&f, parse->ast, id->identity->text->data);
+               scf_logi("ast->current_block: %p, js_type: %d\n", ast->current_block, ast->current_block->node.type);
+               int ret = scf_ast_find_function(&f, ast, id->identity->text->data);
                if (ret < 0)
                        return SCF_DFA_ERROR;
 
@@ -84,7 +86,7 @@ static int _call_action_lp(scf_dfa_t* dfa, scf_vector_t* words, void* data)
                        scf_variable_free(var_pf);
                        var_pf = NULL;
                } else {
-                       ret = scf_ast_find_variable(&var_pf, parse->ast, id->identity->text->data);
+                       ret = scf_ast_find_variable(&var_pf, ast, id->identity->text->data);
                        if (ret < 0)
                                return SCF_DFA_ERROR;
 
@@ -93,25 +95,23 @@ static int _call_action_lp(scf_dfa_t* dfa, scf_vector_t* words, void* data)
                                return SCF_DFA_ERROR;
                        }
 
-                       if (SCF_FUNCTION_PTR != var_pf->type || !var_pf->func_ptr) {
-                               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;
+                       if (SCF_FUNCTION_PTR == var_pf->type) {
+                               if (!var_pf->func_ptr) {
+                                       scf_loge("invalid function ptr\n");
+                                       return SCF_DFA_ERROR;
+                               }
+                       } else {
+                               ret = scf_ast_find_type(&Object, ast, "Object");
+                               if (ret < 0)
+                                       return SCF_DFA_ERROR;
 
-                               scf_loge("f: %s\n", f->node.w->text->data);
-                               node_pf = scf_node_alloc(NULL, v2->type, v2);
+                               if (Object->type != var_pf->type) {
+                                       scf_loge("invalid function ptr\n");
+                                       return SCF_DFA_ERROR;
+                               }
+                       }
 
-                               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) {
@@ -289,8 +289,8 @@ static int _call_action_rp(scf_dfa_t* dfa, scf_vector_t* words, void* data)
        scf_variable_t*  r;
        scf_function_t*  f;
        scf_expr_t*      e;
-       scf_type_t*       = NULL;
-       scf_node_t*      pf = cd->call->nodes[0];
+       scf_type_t*      Object = NULL;
+       scf_node_t*      pf     = cd->call->nodes[0];
 
        while (SCF_OP_EXPR == pf->type)
                pf = pf->nodes[0];
@@ -298,23 +298,24 @@ static int _call_action_rp(scf_dfa_t* dfa, scf_vector_t* words, void* data)
        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");
+       int ret = scf_ast_find_type(&Object, 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 (SCF_FUNCTION_PTR == pf->type) {
+               f = pf->var->func_ptr;
+
+               scf_logw("f: %s, f->js_flag: %d\n", f->node.w->text->data, f->js_flag);
+       } else
+               assert(Object->type == pf->type);
 
        if (cd->argv) {
                int 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 (pf->type == Object->type) {
+                               ret = _call_add_obj(parse->ast, w, cd->call, e, Object);
                                if (ret < 0)
                                        return ret;
                        }
@@ -328,8 +329,8 @@ 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 (pf->type == Object->type) {
+                       ret = _call_add_obj(parse->ast, w, cd->call, d->expr, Object);
                        if (ret < 0)
                                return ret;
                }
index e05c1bf699c18f192207beaf3ba55ab1738056a2..7f8c3b461da9ad32783bde240aa2327d59eebe63 100644 (file)
@@ -190,7 +190,6 @@ 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;
index 5cf7336fe890fa62836475fed29b120046a2c384..62590a30edd076106fb04040eaedfe2706b12920 100644 (file)
@@ -7,7 +7,6 @@ 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;
 
@@ -148,8 +147,6 @@ static int _function_js_action_lp(scf_dfa_t* dfa, scf_vector_t* words, void* dat
        assert(!d->current_node);
 
        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)
@@ -258,66 +255,15 @@ static int _function_js_action_end(scf_dfa_t* dfa, scf_vector_t* words, void* da
        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);
-       }
+       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;
        fd->parent_block = NULL;
-       fd->parent_expr  = NULL;
-       fd->parent_var   = NULL;
 
        if (d->current_function->member_flag) {
 
@@ -328,9 +274,7 @@ 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_NEXT_WORD;
        return SCF_DFA_OK;
 }
 
index 03317ce4ec6384be655724ae5005d6df28d25dee..c4ce9ad075b9db1a99c600ffbbaef70718c38250 100644 (file)
@@ -1573,8 +1573,10 @@ static int _scf_op_semantic_call(scf_ast_t* ast, scf_node_t** nodes, int nb_node
        scf_variable_t*     v1;
        scf_variable_t*     v;
        scf_function_t*     f;
-       scf_node_t*         p;
+       scf_type_t*         t;
+       scf_type_t*         Object = NULL;
        scf_node_t*         parent = nodes[0]->parent;
+       scf_node_t*         p;
        scf_node_t*         this;
 
        d->pret = &nodes[0]->result;
@@ -1587,12 +1589,22 @@ static int _scf_op_semantic_call(scf_ast_t* ast, scf_node_t** nodes, int nb_node
        }
 
        v0 = _scf_operand_get(nodes[0]);
-
-       if (SCF_FUNCTION_PTR != v0->type || !v0->func_ptr) {
+       if (!v0->func_ptr) {
                scf_loge("\n");
                return -1;
        }
 
+       if (SCF_FUNCTION_PTR != v0->type) {
+               ret = scf_ast_find_type(&Object, ast, "Object");
+               if (ret < 0)
+                       return ret;
+
+               if (v0->type != Object->type) {
+                       scf_loge("\n");
+                       return -1;
+               }
+       }
+
        f = v0->func_ptr;
 
        if (f->member_flag) { // add 'this' pointer for member function
@@ -1601,38 +1613,18 @@ 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];
 
-               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;
+               if (SCF_OP_POINTER == p->type) {
+                       assert(2 == p->nb_nodes);
 
-                               scf_logi("this: %p\n", this);
-                               break;
-                       default:
-                               scf_loge("\n");
-                               return -1;
-                               break;
-               };
+                       this = p->nodes[0];
 
-               scf_node_add_child(parent, this);
+                       scf_node_add_child(parent, this);
 
-               int i;
-               for (i = parent->nb_nodes - 2; i >= 1; i--)
-                       parent->nodes[i + 1] = parent->nodes[i];
-               parent->nodes[1] = this;
+                       int i;
+                       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];
@@ -1646,24 +1638,60 @@ static int _scf_op_semantic_call(scf_ast_t* ast, scf_node_t** nodes, int nb_node
 
                        scf_node_free(p);
                        p = NULL;
+               } else {
+                       ret = scf_ast_find_variable(&v, ast, "document");
+                       if (ret < 0)
+                               return ret;
+
+                       if (nb_nodes < 2 || _scf_operand_get(nodes[1]) != v) {
+
+                               this = scf_node_alloc(NULL, v->type, v);
+                               if (!this)
+                                       return -ENOMEM;
+
+                               scf_node_add_child(parent, this);
+
+                               int i;
+                               for (i = parent->nb_nodes - 2; i >= 1; i--)
+                                       parent->nodes[i + 1] = parent->nodes[i];
+                               parent->nodes[1] = this;
+
+                               scf_logi("f: %s(), this: %p, p->type: %d\n", f->node.w->text->data, this, p->type);
+                       }
                }
 
-               nb_nodes++;
+               if (f->js_flag) {
+                       p = parent->nodes[0];
+                       while (p && SCF_OP_EXPR == p->type)
+                               p = p->nodes[0];
+
+                       t = scf_block_find_type_type(ast->current_block, SCF_FUNCTION_PTR);
+                       v = SCF_VAR_ALLOC_BY_TYPE(f->node.w, t, 1, 1, f);
+                       if (!v)
+                               return -ENOMEM;
+                       v->const_literal_flag = 1;
+
+                       scf_node_free_data(p);
+
+                       p->type = SCF_FUNCTION_PTR;
+                       p->var  = v;
+               }
        }
 
        if (f->vargs_flag) {
-               if (f->argv->size > nb_nodes - 1) {
+               if (f->argv->size > parent->nb_nodes - 1) {
                        scf_loge("number of args pass to '%s()' at least needs %d, real: %d, file: %s, line: %d\n",
-                                       f->node.w->text->data, f->argv->size, nb_nodes - 1, parent->w->file->data, parent->w->line);
+                                       f->node.w->text->data, f->argv->size, parent->nb_nodes - 1, parent->w->file->data, parent->w->line);
                        return -1;
                }
-       } else if (f->argv->size != nb_nodes - 1) {
+       } else if (f->argv->size != parent->nb_nodes - 1) {
                scf_loge("number of args pass to '%s()' needs %d, real: %d, file: %s, line: %d\n",
-                               f->node.w->text->data, f->argv->size, nb_nodes - 1, parent->w->file->data, parent->w->line);
+                               f->node.w->text->data, f->argv->size, parent->nb_nodes - 1, parent->w->file->data, parent->w->line);
+               assert(0);
                return -1;
        }
 
-       scf_logi("f: %s, f->argv->size: %d, nb_nodes: %d\n", f->node.w->text->data, f->argv->size, nb_nodes);
+       scf_logi("f: %s, f->argv->size: %d, nb_nodes: %d\n", f->node.w->text->data, f->argv->size, parent->nb_nodes);
 
        int i;
        for (i = 0; i < f->argv->size; i++) {
@@ -2880,6 +2908,9 @@ static int _scf_op_semantic_assign(scf_ast_t* ast, scf_node_t** nodes, int nb_no
                                return ret;
                        assert(t);
 
+                       if (!strcmp(t->name->data, "Object") && SCF_FUNCTION_PTR == v1->type)
+                               v0->func_ptr = v1->func_ptr;
+
                        if (scf_scope_find_function(t->scope, "__init")) {
 
                                int ret = _semantic_do_create(ast, nodes, nb_nodes, d);
index 5f78ea99702fb522dd8904557ca19ad5c1c3b06d..aa89b4c976c83c02aeca8bb73461d592dd7c89b1 100644 (file)
@@ -74,8 +74,6 @@ 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;