js: support variable args of js function() with 'arguments[]' array
authoryu.dongliang <18588496441@163.com>
Thu, 25 Sep 2025 13:47:39 +0000 (21:47 +0800)
committeryu.dongliang <18588496441@163.com>
Thu, 25 Sep 2025 13:47:49 +0000 (21:47 +0800)
29 files changed:
examples/js.html
examples/js2.html [new file with mode: 0644]
html/Makefile
html/abc_html.c
js/abc_libjs.c
js/abc_libjs.so
js/core/scf_3ac.c
js/core/scf_basic_block.c
js/core/scf_function.c
js/core/scf_function.h
js/core/scf_node.h
js/core/scf_operator_handler_3ac.c
js/core/scf_optimizer.c
js/core/scf_optimizer_auto_gc_find.c
js/core/scf_optimizer_js_array.c [new file with mode: 0644]
js/core/scf_optimizer_js_call.c [new file with mode: 0644]
js/core/scf_variable.h
js/doc.c
js/parse/scf_dfa_call.c
js/parse/scf_dfa_class.c
js/parse/scf_dfa_enum.c
js/parse/scf_dfa_expr.c
js/parse/scf_dfa_function.c
js/parse/scf_dfa_function_js.c
js/parse/scf_dfa_init_data.c
js/parse/scf_dfa_switch.c
js/parse/scf_operator_handler_semantic.c
js/parse/scf_parse.h
ui/Makefile

index 146d3e43b65fa84e3bfdb28c59e2bf3aca90184a..e6b57d1520136dc171cc1e41fa6201142f121028 100644 (file)
@@ -7,12 +7,13 @@
 <p>含有js的页面</p>
 
 <script>
+function f()
+{
+       document.write(arguments.length);
+}
 
-var a = function(x, y) {
-               return x + y;
-       };
+f("hello", "world");
 
-document.write(a(1, 2));
 </script>
 
 </body>
diff --git a/examples/js2.html b/examples/js2.html
new file mode 100644 (file)
index 0000000..871481e
--- /dev/null
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<html>
+<body>
+
+<h1>含有javascript的页面</h1>
+
+<p>含有js的页面</p>
+
+<script>
+function f(a, b)
+{
+       return a + b;
+}
+
+var c = f(1, 2);
+
+document.write(c);
+
+</script>
+
+</body>
+</html>
index 1d21c3604a87d42561ddbcc060cf8df31eab36c6..37acf100c610fd7dde2d65b04ea223a0991ffd8b 100644 (file)
@@ -105,6 +105,10 @@ CFILES += ../js/core/scf_pointer_alias.c
 CFILES += ../js/core/scf_optimizer.c
 CFILES += ../js/core/scf_optimizer_dag.c
 CFILES += ../js/core/scf_optimizer_inline.c
+
+CFILES += ../js/core/scf_optimizer_js_array.c
+CFILES += ../js/core/scf_optimizer_js_call.c
+
 CFILES += ../js/core/scf_optimizer_split_call.c
 CFILES += ../js/core/scf_optimizer_call.c
 CFILES += ../js/core/scf_optimizer_common_expr.c
index 5e48e3b98364f98714090773c969fd446db24324..f47710a8b3160310ae8d112d7dc2933c174fe647 100644 (file)
@@ -593,6 +593,7 @@ static int __html_parse_text(abc_html_t* html, abc_obj_t* obj)
 
        abc_char_t* c = NULL;
 
+       int flag = 0;
        while (1) {
                c = __html_pop_char(html);
                if (!c) {
@@ -601,8 +602,13 @@ static int __html_parse_text(abc_html_t* html, abc_obj_t* obj)
                        return -1;
                }
 
-               if ('<' == c->c)
-                       break;
+               if ('\'' == c->c || '\"' == c->c)
+                       flag = !flag;
+
+               if (!flag) {
+                       if ('<' == c->c)
+                               break;
+               }
 
                if ('\n' == c->c) {
                        html->n_lines++;
@@ -869,44 +875,45 @@ static int __html_parse_attr(abc_html_t* html, abc_obj_t* obj, const html_attr_t
 
 static int __html_js_path(scf_string_t** ppath, abc_obj_t* obj, const char* prefix, const char* ext, int dir_flag)
 {
-       if (*ppath)
-               scf_string_free(*ppath);
-
-       *ppath = scf_string_alloc();
-       if (!*ppath)
+       scf_string_t* path = scf_string_alloc();
+       if (!path)
                return -ENOMEM;
 
+       int ret = 0;
+
        if (dir_flag) {
                char* cwd = get_current_dir_name();
-               if (!cwd)
+               if (!cwd) {
+                       scf_string_free(path);
                        return -ENOMEM;
+               }
 
-               int ret = scf_string_cat_cstr(*ppath, cwd);
+               ret = scf_string_cat_cstr(path, cwd);
                free(cwd);
                cwd = NULL;
                if (ret < 0)
-                       return ret;
+                       goto error;
 
-               ret = scf_string_cat_cstr(*ppath, "/");
+               ret = scf_string_cat_cstr(path, "/");
                if (ret < 0)
-                       return ret;
+                       goto error;
        }
 
        if (prefix) {
-               int ret = scf_string_cat_cstr(*ppath, prefix);
+               ret = scf_string_cat_cstr(path, prefix);
                if (ret < 0)
-                       return ret;
+                       goto error;
        }
 
-       int len = (*ppath)->len;
+       int len = path->len;
        int i;
 
-       int ret = scf_string_cat(*ppath, obj->file);
+       ret = scf_string_cat(path, obj->file);
        if (ret < 0)
-               return ret;
+               goto error;
 
-       for (i = len; i < (*ppath)->len; i++) {
-               char c      = (*ppath)->data[i];
+       for (i = len; i < path->len; i++) {
+               char c      = path->data[i];
 
                if ('_' == c
                                || ('0' <= c && c <= '9')
@@ -914,23 +921,31 @@ static int __html_js_path(scf_string_t** ppath, abc_obj_t* obj, const char* pref
                                || ('A' <= c && c <= 'Z'))
                        continue;
 
-               (*ppath)->data[i] = '_';
+               path->data[i] = '_';
        }
 
        char buf[256];
        len = snprintf(buf, sizeof(buf) - 1, "_%d_%d", obj->line, obj->pos);
 
-       ret = scf_string_cat_cstr_len(*ppath, buf, len);
+       ret = scf_string_cat_cstr_len(path, buf, len);
        if (ret < 0)
-               return ret;
+               goto error;
 
        if (ext) {
-               ret = scf_string_cat_cstr(*ppath, ext);
+               ret = scf_string_cat_cstr(path, ext);
                if (ret < 0)
-                       return ret;
+                       goto error;
        }
 
+       if (*ppath)
+               scf_string_free(*ppath);
+
+       *ppath = path;
        return 0;
+
+error:
+       scf_string_free(path);
+       return ret;
 }
 
 static int __html_run_js(abc_html_t* html, abc_obj_t* obj)
@@ -962,6 +977,8 @@ static int __html_run_js(abc_html_t* html, abc_obj_t* obj)
        }
 
        if (obj->text) {
+               scf_logd("obj->text: %s\n", obj->text->data);
+
                ret = scf_parse_file(html->js, obj->js_path->data, obj->text);
                if (ret < 0)
                        return ret;
index c43216d761cd8f54197958bbde5df44d1f0aeaec..a6069103c1a1634fb7b32c501ec896b3d6b2f58a 100644 (file)
@@ -96,3 +96,19 @@ error:
        }
        return -1;
 }
+
+int abc_html_write_i(abc_html_t* html, int64_t i)
+{
+       char buf[128];
+       snprintf(buf, sizeof(buf) - 1, "%ld", i);
+
+       return abc_html_write(html, buf);
+}
+
+int abc_html_write_d(abc_html_t* html, double d)
+{
+       char buf[128];
+       snprintf(buf, sizeof(buf) - 1, "%lg", d);
+
+       return abc_html_write(html, buf);
+}
index cb2894b91f8825c8ff490375a86190317ca0631c..60fb561ab41edae56d980c62122a562bf3a17cdd 100755 (executable)
Binary files a/js/abc_libjs.so and b/js/abc_libjs.so differ
index 37989c2fa1aba21cd11167fc592afb45ce0e91d7..45a26911876fb190bdce9f3e0fca195bee0abf25 100644 (file)
@@ -502,7 +502,7 @@ void scf_3ac_code_print(scf_3ac_code_t* c, scf_list_t* sentinel)
        }
 
        if (c->srcs) {
-       
+
                for (i  = 0; i < c->srcs->size; i++) {
                        src =        c->srcs->data[i];
 
index b38a2dd2045baedd73a8c0ae0ef459eaa8e7514c..55a642619edc8e1b1fb22205ff72943da1c32345 100644 (file)
@@ -1132,8 +1132,9 @@ int scf_basic_block_active_vars(scf_basic_block_t* bb)
        }
 #endif
 
-       scf_vector_clear(bb->entry_dn_actives, NULL);
-       scf_vector_clear(bb->dn_updateds,      NULL);
+       scf_vector_clear(bb->entry_dn_actives,   NULL);
+       scf_vector_clear(bb->entry_dn_inactives, NULL);
+       scf_vector_clear(bb->dn_updateds,        NULL);
 
        if (!scf_list_empty(&bb->code_list_head)) {
 
@@ -1319,6 +1320,9 @@ int scf_basic_block_loads_saves(scf_basic_block_t* bb, scf_list_t* bb_list_head)
        int ret;
        int i;
 
+       scf_vector_clear(bb->dn_loads, NULL);
+       scf_vector_clear(bb->dn_saves, NULL);
+
        for (i = 0; i < bb->entry_dn_actives->size; i++) {
                dn =        bb->entry_dn_actives->data[i];
 
index 4fe5befe569a735b3fa13d8d9407617ca1cf2257..a8d5e31ecc5645d259c376c7b3f0463f79e5e1d5 100644 (file)
@@ -99,6 +99,11 @@ void scf_function_free(scf_function_t* f)
                        f->signature = NULL;
                }
 
+               if (f->src_code) {
+                       scf_string_free(f->src_code);
+                       f->src_code = NULL;
+               }
+
                if (f->rets) {
                        scf_vector_clear(f->rets, ( void (*)(void*) ) scf_variable_free);
                        scf_vector_free (f->rets);
index 26e074a772b10593599d288ed8b4bb4a78733f7c..c69b4a3cfbc9d65c4ae6def4c60cca4b709c40b1 100644 (file)
@@ -9,6 +9,7 @@ struct scf_function_s {
        scf_scope_t*      scope;
 
        scf_string_t*     signature;
+       scf_string_t*     src_code;
 
        scf_list_t        list; // for scope
 
index 1ad8432986ab6db4a480884d4ceb19c481ec5211..375badd890c72b082efd066db42c3ace9577e168 100644 (file)
@@ -19,6 +19,8 @@ struct scf_node_s {
        int                                     nb_nodes;       // children nodes count
        scf_node_t**            nodes;          // children nodes
 
+       scf_expr_t*         js_create;  // the expr which created this node, only for js!
+
        union {
                scf_variable_t*         var;
                scf_lex_word_t*         w;
@@ -44,6 +46,8 @@ struct scf_node_s {
        uint32_t            split_flag  :1; // set when node is a split node of its parent
        uint32_t            _3ac_done   :1; // set when node's 3ac code is made
 
+       uint32_t            this_done   :1; // set when node is a function call() & its 'this' pointer is set
+
        uint32_t            semi_flag   :1; // set when followed by a ';'
 };
 
index c03304966a10fcd00930619a081e06c55297d602..840b46a6de9e05d87383c83fbb3ef107e6bdf369 100644 (file)
@@ -1677,7 +1677,11 @@ static int _scf_op_expr(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void*
 #if 1
        assert(1 == nb_nodes);
 
-       scf_handler_data_t* d = data;
+       scf_handler_data_t* d      = data;
+       scf_node_t*         parent = nodes[0]->parent;
+
+       if (parent->_3ac_done)
+               return 0;
 
        int ret = _scf_expr_calculate_internal(ast, nodes[0], d);
        if (ret < 0)
index 79fd61caa1bf84caae66354de00a90afc56c86f7..38214e9a831946135efa6cb365517990ce428b06 100644 (file)
@@ -1,6 +1,9 @@
 #include"scf_optimizer.h"
 
 extern scf_optimizer_t   scf_optimizer_inline;
+extern scf_optimizer_t   scf_optimizer_js_array;
+extern scf_optimizer_t   scf_optimizer_js_call;
+
 extern scf_optimizer_t   scf_optimizer_split_call;
 
 extern scf_optimizer_t   scf_optimizer_dag;
@@ -32,6 +35,9 @@ extern scf_optimizer_t   scf_optimizer_generate_loads_saves;
 static scf_optimizer_t*  scf_optimizers[] =
 {
        &scf_optimizer_inline, // global optimizer
+       &scf_optimizer_js_array,
+       &scf_optimizer_js_call,
+
        &scf_optimizer_split_call,
 
        &scf_optimizer_dag,
@@ -46,14 +52,15 @@ static scf_optimizer_t*  scf_optimizers[] =
        &scf_optimizer_loads_saves,
 
        &scf_optimizer_auto_gc_find, // global optimizer
-
        &scf_optimizer_dominators,
-
        &scf_optimizer_auto_gc,
 
        &scf_optimizer_basic_block,
        &scf_optimizer_const_teq,
 
+       &scf_optimizer_active_vars,
+       &scf_optimizer_loads_saves,
+
        &scf_optimizer_dominators,
        &scf_optimizer_loop,
        &scf_optimizer_vla,
index ae9b6f39f4c7c2ae8f0fc7fb7d8f48ea5ab8328e..9cf8a6cb404d013ff330899deebf42c4215f34ee 100644 (file)
@@ -344,6 +344,8 @@ static int _auto_gc_find_argv_out(scf_basic_block_t* cur_bb, scf_3ac_code_t* c)
 
 static int _auto_gc_find_ret(scf_basic_block_t* cur_bb, scf_3ac_code_t* c)
 {
+       if (!c->dsts)
+               return 0;
        assert(c->srcs->size > 0);
 
        scf_3ac_operand_t* dst;
@@ -501,17 +503,16 @@ static int _auto_gc_find_ref(scf_dn_status_t* ds_obj, scf_dag_node_t* dn, scf_3a
                }
 
                if (fret->auto_gc_flag) {
-                       _bb_add_ds        (cur_bb, ds_obj);
-                       _bb_add_ds_for_ret(cur_bb, ds_obj, f2);
-
                        ds = scf_dn_status_alloc(dn);
                        if (!ds)
                                return -ENOMEM;
-
                        _bb_del_ds(cur_bb, ds);
 
                        scf_dn_status_free(ds);
                        ds = NULL;
+
+                       _bb_add_ds        (cur_bb, ds_obj);
+                       _bb_add_ds_for_ret(cur_bb, ds_obj, f2);
                        return 2;
                }
        } else {
@@ -849,7 +850,6 @@ static int _auto_gc_function_find(scf_ast_t* ast, scf_function_t* f, scf_list_t*
                                0xffff & (uintptr_t)ds, ds->ret_flag, ds->ret_index, ds->dag_node->var->arg_flag);
                scf_dn_status_print(ds);
 #endif
-
                if (ds->dag_node->var->arg_flag)
                        ds->dag_node->var->auto_gc_flag = 1;
                else {
diff --git a/js/core/scf_optimizer_js_array.c b/js/core/scf_optimizer_js_array.c
new file mode 100644 (file)
index 0000000..e5899cf
--- /dev/null
@@ -0,0 +1,126 @@
+#include"scf_optimizer.h"
+#include"scf_pointer_alias.h"
+
+static int __js_array_realloc(scf_ast_t* ast, scf_3ac_code_t** pc, scf_node_t* array, scf_node_t* index)
+{
+       scf_3ac_code_t*  c;
+       scf_variable_t*  v;
+       scf_function_t*  f = NULL;
+       scf_type_t*      t = NULL;
+       scf_node_t*      pf;
+
+       int ret = scf_ast_find_global_function(&f, ast, "Object_array_realloc");
+       if (ret < 0)
+               return ret;
+
+       ret = scf_ast_find_type_type(&t, ast, SCF_FUNCTION_PTR);
+       if (ret < 0)
+               return ret;
+
+       v = SCF_VAR_ALLOC_BY_TYPE(f->node.w, t, 1, 1, f);
+       if (!v)
+               return -ENOMEM;
+       v->const_literal_flag = 1;
+
+       pf = scf_node_alloc(NULL, v->type, v);
+       scf_variable_free(v);
+       v = NULL;
+       if (!pf)
+               return -ENOMEM;
+
+       scf_node_t* srcs[3] = {pf, array, index};
+
+       c = scf_3ac_code_NN(SCF_OP_CALL, NULL, 0, srcs, 3);
+       if (!c) {
+               scf_node_free(pf);
+               return -ENOMEM;
+       }
+
+       *pc = c;
+       return 0;
+}
+
+static int _optimize_js_array_bb(scf_ast_t* ast, scf_basic_block_t* bb, scf_list_t* bb_list_head)
+{
+       scf_3ac_operand_t* base;
+       scf_3ac_operand_t* index;
+       scf_3ac_code_t*    c;
+       scf_3ac_code_t*    c2;
+       scf_variable_t*    v;
+       scf_node_t*        array;
+       scf_type_t*        Object = NULL;
+       scf_list_t*        l;
+
+       int ret = scf_ast_find_global_type(&Object, ast, "Object");
+       if (ret < 0)
+               return ret;
+
+       for (l = scf_list_head(&bb->code_list_head); l != scf_list_sentinel(&bb->code_list_head); ) {
+
+               c  = scf_list_data(l, scf_3ac_code_t, list);
+               l  = scf_list_next(l);
+
+               if (SCF_OP_ARRAY_INDEX == c->op->type || scf_type_is_assign_array_index(c->op->type)) {
+                       base  = c->srcs->data[0];
+                       index = c->srcs->data[1];
+                       array = base->node;
+
+                       while (SCF_OP_EXPR == array->type || SCF_OP_POINTER == array->type)
+                               array = array->nodes[0];
+
+                       v = _scf_operand_get(array);
+
+                       if (v->type == Object->type) {
+                               c2  = NULL;
+                               ret = __js_array_realloc(ast, &c2, array, index->node);
+                               if (ret < 0)
+                                       return ret;
+
+                               c2->basic_block = c->basic_block;
+
+                               assert(scf_list_prev(&c->list) != scf_list_sentinel(&bb->code_list_head));
+
+                               scf_list_add_tail(scf_list_prev(&c->list), &c2->list);
+                       }
+               }
+       }
+
+       return 0;
+}
+
+static int _optimize_js_array(scf_ast_t* ast, scf_function_t* f, scf_vector_t* functions)
+{
+       if (!f)
+               return -EINVAL;
+
+       scf_list_t*        bb_list_head = &f->basic_block_list_head;
+       scf_list_t*        l;
+       scf_basic_block_t* bb;
+
+       if (scf_list_empty(bb_list_head))
+               return 0;
+
+       for (l = scf_list_head(bb_list_head); l != scf_list_sentinel(bb_list_head); ) {
+
+               bb = scf_list_data(l, scf_basic_block_t, list);
+               l  = scf_list_next(l);
+
+               if (bb->jmp_flag || bb->end_flag || bb->cmp_flag)
+                       continue;
+
+               int ret = _optimize_js_array_bb(ast, bb, bb_list_head);
+               if (ret < 0)
+                       return ret;
+       }
+
+       return 0;
+}
+
+scf_optimizer_t  scf_optimizer_js_array =
+{
+       .name     =  "js_array",
+
+       .optimize =  _optimize_js_array,
+
+       .flags    = SCF_OPTIMIZER_LOCAL,
+};
diff --git a/js/core/scf_optimizer_js_call.c b/js/core/scf_optimizer_js_call.c
new file mode 100644 (file)
index 0000000..2f5eca3
--- /dev/null
@@ -0,0 +1,146 @@
+#include"scf_optimizer.h"
+#include"scf_pointer_alias.h"
+
+static int __js_call_arguments(scf_ast_t* ast, scf_3ac_code_t** pc, scf_node_t* arguments, int i, scf_node_t* arg)
+{
+       scf_3ac_code_t*  c;
+       scf_variable_t*  v;
+       scf_function_t*  f = NULL;
+       scf_type_t*      t = NULL;
+       scf_node_t*      pf;
+       scf_node_t*      index;
+
+       int ret = scf_ast_find_global_function(&f, ast, "Object_func_arguments");
+       if (ret < 0)
+               return ret;
+
+       ret = scf_ast_find_type_type(&t, ast, SCF_FUNCTION_PTR);
+       if (ret < 0)
+               return ret;
+
+       v = SCF_VAR_ALLOC_BY_TYPE(f->node.w, t, 1, 1, f);
+       if (!v)
+               return -ENOMEM;
+       v->const_literal_flag = 1;
+
+       pf = scf_node_alloc(NULL, v->type, v);
+       scf_variable_free(v);
+       v = NULL;
+       if (!pf)
+               return -ENOMEM;
+
+       // index
+       ret = scf_ast_find_type_type(&t, ast, SCF_VAR_INT);
+       if (ret < 0)
+               return ret;
+
+       v = SCF_VAR_ALLOC_BY_TYPE(NULL, t, 1, 0, NULL);
+       if (!v)
+               return -ENOMEM;
+       v->data.u64 = i;
+       v->const_literal_flag = 1;
+
+       index = scf_node_alloc(NULL, v->type, v);
+       scf_variable_free(v);
+       v = NULL;
+       if (!index)
+               return -ENOMEM;
+
+       scf_node_t* srcs[] = {pf, arguments, index, arg};
+
+       c = scf_3ac_code_NN(SCF_OP_CALL, NULL, 0, srcs, 4);
+       if (!c) {
+               scf_node_free(index);
+               scf_node_free(pf);
+               return -ENOMEM;
+       }
+
+       *pc = c;
+       return 0;
+}
+
+static int _optimize_js_call_bb(scf_ast_t* ast, scf_basic_block_t* bb, scf_list_t* bb_list_head)
+{
+       scf_3ac_operand_t* src;
+       scf_3ac_operand_t* args;
+       scf_3ac_code_t*    c;
+       scf_3ac_code_t*    c2;
+       scf_variable_t*    v;
+       scf_function_t*    f;
+       scf_node_t*        array;
+       scf_type_t*        Object = NULL;
+       scf_list_t*        l;
+
+       int ret = scf_ast_find_global_type(&Object, ast, "Object");
+       if (ret < 0)
+               return ret;
+
+       for (l = scf_list_head(&bb->code_list_head); l != scf_list_sentinel(&bb->code_list_head); ) {
+
+               c  = scf_list_data(l, scf_3ac_code_t, list);
+               l  = scf_list_next(l);
+
+               if (SCF_OP_CALL != c->op->type)
+                       continue;
+
+               src = c->srcs->data[0];
+               f   = _scf_operand_get(src->node)->func_ptr;
+
+               if (!f->js_flag || !f->vargs_flag)
+                       continue;
+               args = c->srcs->data[2];
+
+               int i;
+               for (i = 3; i < c->srcs->size; i++) {
+                       src       = c->srcs->data[i];
+
+                       c2  = NULL;
+                       ret = __js_call_arguments(ast, &c2, args->node, i - 3, src->node);
+                       if (ret < 0)
+                               return ret;
+
+                       c2->basic_block = c->basic_block;
+
+                       scf_list_add_tail(&c->list, &c2->list);
+               }
+       }
+
+       return 0;
+}
+
+static int _optimize_js_call(scf_ast_t* ast, scf_function_t* f, scf_vector_t* functions)
+{
+       if (!f)
+               return -EINVAL;
+
+       scf_list_t*        bb_list_head = &f->basic_block_list_head;
+       scf_list_t*        l;
+       scf_basic_block_t* bb;
+
+       if (scf_list_empty(bb_list_head))
+               return 0;
+
+       for (l = scf_list_head(bb_list_head); l != scf_list_sentinel(bb_list_head); ) {
+
+               bb = scf_list_data(l, scf_basic_block_t, list);
+               l  = scf_list_next(l);
+
+               if (bb->jmp_flag || bb->end_flag || bb->cmp_flag)
+                       continue;
+
+               int ret = _optimize_js_call_bb(ast, bb, bb_list_head);
+               if (ret < 0)
+                       return ret;
+       }
+
+       return 0;
+}
+
+scf_optimizer_t  scf_optimizer_js_call =
+{
+       .name     =  "js_call",
+
+       .optimize =  _optimize_js_call,
+
+       .flags    = SCF_OPTIMIZER_LOCAL,
+};
index 1d560a14b07a36439d1e59497d009026554eb89f..96e695db9bfbd8717902f7aa352a68e3ffb00e99 100644 (file)
@@ -18,6 +18,7 @@ struct scf_variable_s {
 
        int                 js_type;
        int                 js_index;
+       scf_variable_t*     js_var;
 
        int                 nb_lbs; // number of '{}' when parse js object
        int                 nb_rbs;
index 171108871c55c47927f2a5207aebc9c1fd56da03..c1aa9c2b8516d89c9315d3cb546fefb0e434bb60 100644 (file)
--- a/js/doc.c
+++ b/js/doc.c
@@ -2,12 +2,21 @@
 
 struct Object;
 
-int abc_html_write(Object* html, const char* s);
+int abc_html_write  (Object* html, const char* s);
+int abc_html_write_i(Object* html, int64_t i);
+int abc_html_write_d(Object* html, double  d);
+
+enum {
+       JS_Undef,
+       JS_Number,
+       JS_String,
+       JS_Object,
+};
 
 struct Object
 {
        int       type;
-       int       n_members;
+       int       length;
        Object**  members;
        char*     name;
 // p.x --> p.members[x]
@@ -16,22 +25,35 @@ struct Object
 
        int __init(Object* this, double d)
        {
-               this->d = d;
+               this->d    = d;
+               this->type = JS_Number;
+               printf("this: %p, this->d: %lg, d: %lg\n\n", this, this->d, d);
                return 0;
        }
 
        int __init(Object* this, int64_t d)
        {
-               this->d = d;
+               this->d    = d;
+               this->type = JS_Number;
+               printf("this: %p, this->d: %lg, d: %ld\n\n", this, this->d, d);
                return 0;
        }
 
-       int __init(Object* this, void* p)
+       int __init(Object* this, const char* s)
        {
+               int len = strlen(s);
+
+               this->str = scf__auto_malloc(len + 1);
+               if (!this->str)
+                       return -1;
+
+               memcpy(this->str, s, len + 1);
+
+               this->type = JS_String;
                return 0;
        }
 
-       int __init(Object* this, const char* name, int n_members)
+       int __init(Object* this, const char* name, int length)
        {
                printf("this: %p, name: %s\n", this, name);
                int len = strlen(name);
@@ -41,19 +63,21 @@ struct Object
                        return -1;
                memcpy(this->name, name, len + 1);
 
-               this->n_members = n_members;
+               this->length = length;
 
-               if (n_members > 0) {
-                       this->members = scf__auto_malloc(sizeof(Object*) * n_members);
+               if (length > 0) {
+                       this->members = scf__auto_malloc(sizeof(Object*) * length);
                        if (!this->members)
                                return -1;
                }
 
                printf("\n");
+
+               this->type = JS_Object;
                return 0;
        }
 
-       int __init(Object* this, const char* name, int n_members, double d)
+       int __init(Object* this, const char* name, int length, double d)
        {
                printf("this: %p, name: %s\n", this, name);
                int len = strlen(name);
@@ -63,27 +87,75 @@ struct Object
                        return -1;
                memcpy(this->name, name, len + 1);
 
-               this->n_members = n_members;
+               this->length = length;
 
-               if (n_members > 0) {
-                       this->members = scf__auto_malloc(sizeof(Object*) * n_members);
+               if (length > 0) {
+                       this->members = scf__auto_malloc(sizeof(Object*) * length);
                        if (!this->members)
                                return -1;
-               }
+
+                       this->type = JS_Object;
+               } else
+                       this->type = JS_Number;
 
                this->d = d;
 
-               printf("this: %p, this->d: %lg, d: %lg\n", this, this->d, d);
+               printf("this: %p, this->d: %lg, d: %lg\n\n", this, this->d, d);
                return 0;
        }
 
        const char* toString(Object* this)
        {
-               char* s = scf__auto_malloc(128);
-               if (!s)
-                       return NULL;
+               char* p;
+               char* s;
+               int   len;
+               int   type = JS_Undef;
+
+               if (this)
+                       type = this->type;
+
+               switch (type) {
+                       case JS_Number:
+                               s = scf__auto_malloc(128);
+                               if (!s)
+                                       return NULL;
+
+                               snprintf(s, 127, "%lg", this->d);
+                               break;
+
+                       case JS_String:
+                               len = strlen(this->str);
+
+                               s = scf__auto_malloc(len + 1);
+                               if (!s)
+                                       return NULL;
+
+                               memcpy(s, this->str, len + 1);
+                               break;
+
+                       case JS_Object:
+                               p   = "[object Object]";
+                               len = strlen(p);
+
+                               s = scf__auto_malloc(len + 1);
+                               if (!s)
+                                       return NULL;
+
+                               memcpy(s, p, len + 1);
+                               break;
+
+                       default:
+                               p   = "undefined";
+                               len = strlen(p);
+
+                               s = scf__auto_malloc(len + 1);
+                               if (!s)
+                                       return NULL;
+
+                               memcpy(s, p, len + 1);
+                               break;
+               };
 
-               snprintf(s, 127, "%lg", this->d);
                return s;
        }
 
@@ -93,6 +165,21 @@ struct Object
                abc_html_write(this, s);
        }
 
+       void write(Object* this, const char* s)
+       {
+               abc_html_write(this, s);
+       }
+
+       void write(Object* this, int64_t i)
+       {
+               abc_html_write_i(this, i);
+       }
+
+       void write(Object* this, double d)
+       {
+               abc_html_write_i(this, d);
+       }
+
        Object* operator+(Object* this, Object* that)
        {
                Object* res = create Object(this->d + that->d);
@@ -103,7 +190,7 @@ struct Object
        {
                if (this->members) {
                        int i;
-                       for (i = 0; i < this->n_members; i++) {
+                       for (i = 0; i < this->length; i++) {
                                if (this->members[i]) {
                                        this->members[i].__release();
 
@@ -124,6 +211,35 @@ struct Object
        }
 };
 
+void Object_func_arguments(Object* this, int i, Object* arg)
+{
+       if (i < this->length) {
+               scf__auto_ref(arg);
+               this->members[i] = arg;
+       }
+}
+
+int Object_array_realloc(Object* this, int i)
+{
+       if (i < this->length)
+               return 0;
+
+       int   n = i + 1;
+       void* p = scf__auto_malloc(sizeof(Object*) * n);
+       if (!p)
+               return -1;
+
+       if (this->length > 0) {
+               memcpy(p, this->members, sizeof(Object*) * this->length);
+
+               scf__auto_freep(&this->members, NULL);
+       }
+
+       this->members = p;
+       this->length  = n;
+       return 0;
+}
+
 Object* document = NULL;
 
 void __js_main(Object* doc)
index 18a26add0b74e183ededf798a5600cab2f3cd2b7..d90ac7606987c0f0d3498a003a72b108c1ec6c79 100644 (file)
@@ -147,6 +147,11 @@ static int _call_action_lp(scf_dfa_t* dfa, scf_vector_t* words, void* data)
        d->expr            = NULL;
        d->expr_local_flag++;
 
+       if (d->parent_block) {
+               ast->current_block = d->parent_block;
+               d->parent_block    = NULL;
+       }
+
        scf_stack_push(s, cd);
 
        SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "call_rp"),      SCF_DFA_HOOK_POST);
@@ -156,6 +161,139 @@ static int _call_action_lp(scf_dfa_t* dfa, scf_vector_t* words, void* data)
        return SCF_DFA_NEXT_WORD;
 }
 
+static int _call_add_arguments(scf_ast_t* ast, scf_lex_word_t* w, int n_members, scf_expr_t* e, scf_type_t* Object)
+{
+       scf_variable_t*  v;
+       scf_block_t*     b;
+       scf_type_t*      pt = scf_block_find_type_type(ast->current_block, SCF_FUNCTION_PTR);
+       scf_node_t*      create;
+       scf_node_t*      assign;
+       scf_node_t*      node;
+       scf_node_t*      arguments;
+       scf_expr_t*      e2;
+
+       // add 'arguments'
+       v = SCF_VAR_ALLOC_BY_TYPE(w, Object, 0, 1, NULL);
+       if (!v)
+               return -ENOMEM;
+
+       arguments = scf_node_alloc(NULL, v->type, v);
+       scf_variable_free(v);
+       v = NULL;
+       if (!arguments)
+               return -ENOMEM;
+
+       b = scf_block_alloc_cstr("multi_rets");
+       if (!b) {
+               scf_node_free(arguments);
+               return -ENOMEM;
+       }
+
+       int ret = scf_node_add_child((scf_node_t*)b, arguments);
+       if (ret < 0) {
+               scf_node_free(arguments);
+               scf_block_free(b);
+               return ret;
+       }
+
+       assign = scf_node_alloc(w, SCF_OP_ASSIGN, NULL);
+       if (!assign) {
+               scf_block_free(b);
+               return -ENOMEM;
+       }
+
+       ret = scf_node_add_child(assign, (scf_node_t*)b);
+       if (ret < 0) {
+               scf_node_free(assign);
+               scf_block_free(b);
+               return ret;
+       }
+       b = NULL;
+
+       // add create()
+       create = scf_node_alloc(w, SCF_OP_CREATE, NULL);
+       if (!create) {
+               scf_node_free(assign);
+               return -ENOMEM;
+       }
+
+       ret = scf_node_add_child(assign, create);
+       if (ret < 0) {
+               scf_node_free(create);
+               scf_node_free(assign);
+               return ret;
+       }
+
+       // add construct() for obj
+       v = SCF_VAR_ALLOC_BY_TYPE(Object->w, pt, 1, 1, NULL);
+       if (!v) {
+               scf_node_free(assign);
+               return -ENOMEM;
+       }
+       v->const_literal_flag = 1;
+
+       node = scf_node_alloc(NULL, v->type, v);
+       scf_variable_free(v);
+       v = NULL;
+       if (!node) {
+               scf_node_free(assign);
+               return -ENOMEM;
+       }
+
+       ret = scf_node_add_child(create, node);
+       if (ret < 0) {
+               scf_node_free(node);
+               scf_node_free(assign);
+               return ret;
+       }
+
+       // add obj name
+       ret = scf_ast_add_const_str(ast, create, Object->w);
+       if (ret < 0) {
+               scf_node_free(assign);
+               return ret;
+       }
+
+       // add obj members
+       ret = scf_ast_add_const_var(ast, create, SCF_VAR_INT, n_members);
+       if (ret < 0) {
+               scf_node_free(assign);
+               return ret;
+       }
+
+       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;
+       }
+
+       ret = scf_node_add_child((scf_node_t*)ast->current_block, e2);
+       if (ret < 0) {
+               scf_expr_free(e2);
+               return ret;
+       }
+
+       node = scf_node_clone(arguments);
+       if (!node)
+               return -ENOMEM;
+
+       ret = scf_node_add_child(e, node);
+       if (ret < 0) {
+               scf_node_free(node);
+               return ret;
+       }
+
+       e->js_create = e2;
+       return 0;
+}
+
 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;
@@ -250,6 +388,7 @@ static int _call_action_rp(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*   w     = words->data[words->size - 1];
        scf_stack_t*      s     = d->module_datas[dfa_module_call.index];
@@ -287,10 +426,10 @@ 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_function_t*  f      = NULL;
        scf_type_t*      Object = NULL;
        scf_node_t*      pf     = cd->call->nodes[0];
+       scf_expr_t*      e;
 
        while (SCF_OP_EXPR == pf->type)
                pf = pf->nodes[0];
@@ -298,13 +437,16 @@ 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];
 
-       int ret = scf_ast_find_type(&Object, parse->ast, "Object");
+       int ret = scf_ast_find_type(&Object, ast, "Object");
        if (ret < 0)
                return ret;
 
+       int js_flag = 1;
        if (SCF_FUNCTION_PTR == pf->type) {
                f = pf->var->func_ptr;
 
+               js_flag = f->js_flag;
+
                scf_logw("f: %s, f->js_flag: %d\n", f->node.w->text->data, f->js_flag);
        } else
                assert(Object->type == pf->type);
@@ -314,8 +456,8 @@ static int _call_action_rp(scf_dfa_t* dfa, scf_vector_t* words, void* data)
                for (i = 0; i < cd->argv->size; i++) {
                        e  =        cd->argv->data[i];
 
-                       if (pf->type == Object->type) {
-                               ret = _call_add_obj(parse->ast, w, cd->call, e, Object);
+                       if (js_flag) {
+                               ret = _call_add_obj(ast, w, cd->call, e, Object);
                                if (ret < 0)
                                        return ret;
                        }
@@ -329,8 +471,8 @@ static int _call_action_rp(scf_dfa_t* dfa, scf_vector_t* words, void* data)
 
        // the last arg
        if (d->expr) {
-               if (pf->type == Object->type) {
-                       ret = _call_add_obj(parse->ast, w, cd->call, d->expr, Object);
+               if (js_flag) {
+                       ret = _call_add_obj(ast, w, cd->call, d->expr, Object);
                        if (ret < 0)
                                return ret;
                }
@@ -339,6 +481,25 @@ static int _call_action_rp(scf_dfa_t* dfa, scf_vector_t* words, void* data)
                d->expr = NULL;
        }
 
+       if (js_flag) {
+               e = scf_expr_alloc();
+               if (!e)
+                       return -ENOMEM;
+
+               ret = _call_add_arguments(ast, w, cd->call->nb_nodes - 1, e, Object);
+               if (ret < 0)
+                       return ret;
+
+               scf_node_add_child(cd->call, e);
+
+               int i;
+               for (i = cd->call->nb_nodes - 2; i >= 1; i--)
+                       cd->call->nodes[i + 1] = cd->call->nodes[i];
+
+               cd->call->nodes[1] = e;
+               e = NULL;
+       }
+
        if (cd->parent_expr)
                d->expr = cd->parent_expr;
        else
index 17a4a10958a5da1c9ceacf13cfe46001717b2c76..5429e61bd18b4434cd395cb0badbdde475a87e14 100644 (file)
@@ -89,7 +89,7 @@ static int _class_action_lb(scf_dfa_t* dfa, scf_vector_t* words, void* data)
        return SCF_DFA_NEXT_WORD;
 }
 
-int _class_calculate_size(scf_dfa_t* dfa, scf_type_t* s)
+int _class_calculate_size(scf_type_t* s)
 {
        scf_variable_t* v;
 
@@ -192,7 +192,7 @@ static int _class_action_rb(scf_dfa_t* dfa, scf_vector_t* words, void* data)
        dfa_data_t*           d     = data;
        class_module_data_t*  md    = d->module_datas[dfa_module_class.index];
 
-       if (_class_calculate_size(dfa, md->current_class) < 0) {
+       if (_class_calculate_size(md->current_class) < 0) {
                scf_loge("\n");
                return SCF_DFA_ERROR;
        }
index aab35a01151656479ccb1b7719bf30a5afd688a3..d0bdafd302c75457bd4031800c0900cafeeed0ef 100644 (file)
@@ -136,8 +136,6 @@ static int _enum_action_var(scf_dfa_t* dfa, scf_vector_t* words, void* data)
 
        md->current_v = v;
 
-       scf_logi("enum var: '%s', type: %d, size: %d\n", w->text->data, v->type, v->size);
-
        return SCF_DFA_NEXT_WORD;
 }
 
@@ -198,6 +196,8 @@ static int _enum_action_comma(scf_dfa_t* dfa, scf_vector_t* words, void* data)
                d->expr_local_flag--;
        }
 
+       scf_logi("enum var: '%s', value: %ld\n", md->current_v->w->text->data, md->current_v->data.i64);
+
        md->current_v = NULL;
 
        return SCF_DFA_SWITCH_TO;
index 7f8c3b461da9ad32783bde240aa2327d59eebe63..42bb81e4b03aec5e86f80f2b3e6acf37343c0422 100644 (file)
@@ -8,7 +8,7 @@ extern scf_dfa_module_t dfa_module_expr;
 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;
 
@@ -16,6 +16,8 @@ typedef struct {
 
 int _type_find_type(scf_dfa_t* dfa, dfa_identity_t* id);
 
+int _class_calculate_size(scf_type_t* s);
+
 static int _expr_is_expr(scf_dfa_t* dfa, void* word)
 {
        scf_lex_word_t* w = word;
@@ -85,6 +87,7 @@ int _expr_add_var(scf_parse_t* parse, dfa_data_t* d)
        scf_node_t*         node = NULL;
        scf_type_t*         pt   = NULL;
        scf_type_t*         t    = NULL;
+       scf_type_t*         t2   = NULL;
        scf_function_t*     f    = NULL;
        dfa_identity_t*     id   = scf_stack_pop(d->current_identities);
        scf_lex_word_t*     w;
@@ -111,24 +114,50 @@ int _expr_add_var(scf_parse_t* parse, dfa_data_t* d)
                if (scf_ast_find_function(&f, parse->ast, w->text->data) < 0)
                        return SCF_DFA_ERROR;
 
-               if (!f) {
+               if (f) {
+                       var = SCF_VAR_ALLOC_BY_TYPE(id->identity, pt, 1, 1, f);
+                       if (!var)
+                               return -ENOMEM;
+
+                       var->const_literal_flag = 1;
+
+               } else if (md->current_var && md->current_var->js_type >= 0) {
+                       t = NULL;
+                       if (scf_ast_find_type_type(&t, parse->ast, md->current_var->js_type) < 0)
+                               return SCF_DFA_ERROR;
+
+                       t2 = NULL;
+                       if (scf_ast_find_type_type(&t2, parse->ast, SCF_VAR_VAR) < 0)
+                               return SCF_DFA_ERROR;
+
+                       var = SCF_VAR_ALLOC_BY_TYPE(w, t2, 0, 0, NULL);
+                       if (!var)
+                               return -ENOMEM;
+                       var->member_flag = 1;
+
+                       scf_scope_push_var(t->scope, var);
+
+                       if (_class_calculate_size(t) < 0)
+                               return SCF_DFA_ERROR;
+
+               } else {
                        scf_loge("function '%s' not found\n", w->text->data);
                        return SCF_DFA_ERROR;
                }
-
-               var = SCF_VAR_ALLOC_BY_TYPE(id->identity, pt, 1, 1, f);
-               if (!var)
-                       return -ENOMEM;
-
-               var->const_literal_flag = 1;
+       } else {
+               if (d->current_function
+                               && d->current_function->js_flag
+                               && !strcmp(w->text->data, "arguments"))
+                       d->current_function->vargs_flag = 1;
        }
 
        scf_logi("var: %s, member_flag: %d, js_type: %d, line: %d, pos: %d\n", var->w->text->data, var->member_flag, var->js_type, var->w->line, var->w->pos);
 
        if (md->current_var
                        && md->current_var->js_type >= 0
-                       && SCF_FUNCTION_PTR != var->type
-                       && var->member_flag) {
+                       && var->member_flag
+                       && strcmp(var->w->text->data, "length")) {
+
                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);
 
@@ -166,6 +195,7 @@ int _expr_add_var(scf_parse_t* parse, dfa_data_t* d)
                        return -ENOMEM;
                v->const_literal_flag = 1;
                v->data.i64 = var->js_index;
+               v->js_var   = var;
 
                node = scf_node_alloc(w, v->type, v);
                scf_variable_free(v);
@@ -354,7 +384,7 @@ static int _expr_action_op(scf_dfa_t* dfa, scf_vector_t* words, void* data, int
                        if (scf_ast_find_type_type(&t, parse->ast, md->current_var->js_type) < 0)
                                return SCF_DFA_ERROR;
 
-                       scf_loge("t: %p, js_type: %d\n", t, t->type);
+                       scf_logd("t: %p, js_type: %d\n", t, t->type);
                        parse->ast->current_block = (scf_block_t*)t;
                }
        }
@@ -373,6 +403,7 @@ static int _expr_action_binary_op(scf_dfa_t* dfa, scf_vector_t* words, void* dat
        scf_logd("\n");
 
        scf_parse_t*        parse = dfa->priv;
+       scf_ast_t*          ast   = parse->ast;
        dfa_data_t*         d     = data;
        scf_lex_word_t*     w     = words->data[words->size - 1];
        expr_module_data_t* md    = d->module_datas[dfa_module_expr.index];
@@ -383,7 +414,7 @@ static int _expr_action_binary_op(scf_dfa_t* dfa, scf_vector_t* words, void* dat
 
                if (id && id->identity) {
 
-                       v = scf_block_find_variable(parse->ast->current_block, id->identity->text->data);
+                       v = scf_block_find_variable(ast->current_block, id->identity->text->data);
                        if (!v) {
                                scf_logw("'%s' not var\n", id->identity->text->data);
 
@@ -404,14 +435,16 @@ static int _expr_action_binary_op(scf_dfa_t* dfa, scf_vector_t* words, void* dat
        if (SCF_LEX_WORD_ARROW == w->type || SCF_LEX_WORD_DOT == w->type) {
                assert(md->current_struct);
 
-               if (!md->parent_block)
-                       md->parent_block = parse->ast->current_block;
+               if (!d->parent_block)
+                       d->parent_block = ast->current_block;
 
-               parse->ast->current_block = (scf_block_t*)md->current_struct;
+               ast->current_block = (scf_block_t*)md->current_struct;
 
-       } else if (md->parent_block) {
-               parse->ast->current_block = md->parent_block;
-               md->parent_block          = NULL;
+               scf_logi("ast->current_block: %p, js_type: %d\n", ast->current_block, ast->current_block->node.type);
+
+       } else if (d->parent_block) {
+               ast->current_block = d->parent_block;
+               d->parent_block    = NULL;
        }
 
        return _expr_action_op(dfa, words, data, 2);
@@ -434,9 +467,9 @@ static int _expr_action_lp(scf_dfa_t* dfa, scf_vector_t* words, void* data)
        scf_stack_push(md->lp_exprs, d->expr);
        d->expr = e;
 
-       if (md->parent_block) {
-               parse->ast->current_block = md->parent_block;
-               md->parent_block = NULL;
+       if (d->parent_block) {
+               parse->ast->current_block = d->parent_block;
+               d->parent_block = NULL;
        }
 
        return SCF_DFA_NEXT_WORD;
@@ -553,9 +586,9 @@ static int _expr_action_rp(scf_dfa_t* dfa, scf_vector_t* words, void* data)
                }
        }
 
-       if (md->parent_block) {
-               parse->ast->current_block = md->parent_block;
-               md->parent_block          = NULL;
+       if (d->parent_block) {
+               parse->ast->current_block = d->parent_block;
+               d->parent_block           = NULL;
        }
 
        scf_expr_t* parent = scf_stack_pop(md->lp_exprs);
@@ -626,9 +659,9 @@ static int _expr_action_ls(scf_dfa_t* dfa, scf_vector_t* words, void* data)
                }
        }
 
-       if (md->parent_block) {
-               parse->ast->current_block = md->parent_block;
-               md->parent_block = NULL;
+       if (d->parent_block) {
+               parse->ast->current_block = d->parent_block;
+               d->parent_block = NULL;
        }
 
        if (md->current_var->js_type >= 0) {
@@ -698,9 +731,9 @@ static int _expr_action_rs(scf_dfa_t* dfa, scf_vector_t* words, void* data)
                }
        }
 
-       if (md->parent_block) {
-               parse->ast->current_block = md->parent_block;
-               md->parent_block          = NULL;
+       if (d->parent_block) {
+               parse->ast->current_block = d->parent_block;
+               d->parent_block           = NULL;
        }
 
        scf_expr_t* ls_parent = scf_stack_pop(md->ls_exprs);
@@ -820,9 +853,12 @@ static int _expr_fini_expr(scf_parse_t* parse, dfa_data_t* d, int semi_flag)
                        return SCF_DFA_ERROR;
        }
 
-       if (md->parent_block) {
-               parse->ast->current_block = md->parent_block;
-               md->parent_block          = NULL;
+       if (md->current_var)
+               md->current_var = NULL;
+
+       if (d->parent_block) {
+               parse->ast->current_block = d->parent_block;
+               d->parent_block           = NULL;
        }
 
        scf_logd("d->expr: %p\n", d->expr);
@@ -858,7 +894,7 @@ static int _expr_fini_expr(scf_parse_t* parse, dfa_data_t* d, int semi_flag)
                        d->expr = NULL;
                }
 
-               scf_logd("d->expr: %p, d->expr_local_flag: %d\n", d->expr, d->expr_local_flag);
+               scf_logi("d->expr: %p, d->expr_local_flag: %d\n", d->expr, d->expr_local_flag);
        }
 
        return SCF_DFA_OK;
index b5cf9207d77b412d3fd20bc74ee9aa7311c7cde9..fe0748ee1f7e25395c7107792b2a9f77ead901fc 100644 (file)
@@ -279,18 +279,16 @@ static int _function_action_rp(scf_dfa_t* dfa, scf_vector_t* words, void* data)
 
                assert(t->scope);
 
-               if (!strcmp(f->node.w->text->data, "__init")) {
+               if (!strcmp(f->node.w->text->data, "__release")) {
 
-                       fprev = scf_scope_find_same_function(t->scope, f);
-
-               } else {
                        fprev = scf_scope_find_function(t->scope, f->node.w->text->data);
-
-                       if (fprev && !scf_function_same(fprev, f)) {
+                       if (fprev) {
                                scf_loge("function '%s' can't be overloaded, repeated declare first in line: %d, second in line: %d\n",
                                                f->node.w->text->data, fprev->node.w->line, f->node.w->line);
                                return SCF_DFA_ERROR;
                        }
+               } else {
+                       fprev = scf_scope_find_same_function(t->scope, f);
                }
        } else {
                scf_block_t* b = fd->parent_block;
@@ -311,7 +309,6 @@ static int _function_action_rp(scf_dfa_t* dfa, scf_vector_t* words, void* data)
                }
 
                if (fprev && !scf_function_same(fprev, f)) {
-
                        scf_loge("repeated declare function '%s', first in line: %d, second in line: %d, function overloading only can do in class\n",
                                        f->node.w->text->data, fprev->node.w->line, f->node.w->line);
                        return SCF_DFA_ERROR;
index 62590a30edd076106fb04040eaedfe2706b12920..97ff26b34144a2c557f3af2a397c30293a023b17 100644 (file)
@@ -8,6 +8,7 @@ typedef struct {
        scf_block_t*     parent_block;
        scf_expr_t*      parent_expr;
 
+       int              start_word;
 } dfa_fun_data_t;
 
 int _function_js_add_function(scf_dfa_t* dfa, scf_lex_word_t* w, dfa_data_t* d)
@@ -83,11 +84,12 @@ int _function_js_add_arg(scf_ast_t* ast, scf_lex_word_t* w, dfa_data_t* d)
        arg = SCF_VAR_ALLOC_BY_TYPE(w, t, 0, 1, NULL);
        if (!arg)
                return SCF_DFA_ERROR;
+       arg->js_type = t->type;
 
        scf_scope_push_var(d->current_function->scope, arg);
 
-       scf_logi("d->argc: %d, arg->nb_pointers: %d, arg->nb_dimentions: %d\n",
-                       d->argc, arg->nb_pointers, arg->nb_dimentions);
+       scf_logi("d->argc: %d, arg->nb_pointers: %d, arg->nb_dimentions: %d, %s\n",
+                       d->argc, arg->nb_pointers, arg->nb_dimentions, w->text->data);
 
        scf_vector_add(d->current_function->argv, arg);
 
@@ -100,15 +102,6 @@ int _function_js_add_arg(scf_ast_t* ast, scf_lex_word_t* w, dfa_data_t* d)
        return SCF_DFA_NEXT_WORD;
 }
 
-static int _function_js_action_vargs(scf_dfa_t* dfa, scf_vector_t* words, void* data)
-{
-       dfa_data_t* d = data;
-
-       d->current_function->vargs_flag = 1;
-
-       return SCF_DFA_NEXT_WORD;
-}
-
 static int _function_js_action_comma(scf_dfa_t* dfa, scf_vector_t* words, void* data)
 {
        scf_parse_t*     parse = dfa->priv;
@@ -132,6 +125,16 @@ static int _function_js_action_comma(scf_dfa_t* dfa, scf_vector_t* words, void*
        return SCF_DFA_NEXT_WORD;
 }
 
+static int _function_js_action_func(scf_dfa_t* dfa, scf_vector_t* words, void* data)
+{
+       dfa_data_t*      d  = data;
+       dfa_fun_data_t*  fd = d->module_datas[dfa_module_function_js.index];
+
+       fd->start_word = words->size - 1;
+
+       return SCF_DFA_NEXT_WORD;
+}
+
 static int _function_js_action_lp(scf_dfa_t* dfa, scf_vector_t* words, void* data)
 {
        scf_parse_t*     parse = dfa->priv;
@@ -139,6 +142,7 @@ static int _function_js_action_lp(scf_dfa_t* dfa, scf_vector_t* words, void* dat
        dfa_fun_data_t*  fd    = d->module_datas[dfa_module_function_js.index];
        scf_lex_word_t*  w;
        scf_lex_word_t*  this;
+       scf_lex_word_t*  arguments;
 
        if (words->size < 2)
                return SCF_DFA_ERROR;
@@ -176,6 +180,24 @@ static int _function_js_action_lp(scf_dfa_t* dfa, scf_vector_t* words, void* dat
        if (ret < 0)
                return SCF_DFA_ERROR;
 
+       // add 'arguments'
+       arguments = scf_lex_word_alloc(w->file, 0, 0, SCF_LEX_WORD_ID);
+       if (!arguments)
+               return SCF_DFA_ERROR;
+
+       arguments->text = scf_string_cstr("arguments");
+       if (!arguments->text) {
+               scf_lex_word_free(arguments);
+               return SCF_DFA_ERROR;
+       }
+
+       ret = _function_js_add_arg(parse->ast, arguments, d);
+
+       scf_lex_word_free(arguments);
+       arguments = NULL;
+       if (ret < 0)
+               return SCF_DFA_ERROR;
+
        return SCF_DFA_NEXT_WORD;
 }
 
@@ -248,19 +270,70 @@ static int _function_js_action_end(scf_dfa_t* dfa, scf_vector_t* words, void* da
        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_variable_t*  arg;
        scf_type_t*      t;
 
+       int i;
+
        parse->ast->current_block = (scf_block_t*)(fd->parent_block);
 
        if (f->node.nb_nodes > 0)
                f->node.define_flag = 1;
 
-       w = scf_lex_word_clone(f->node.w);
-       if (!w)
-               return -ENOMEM;
-       w->type = SCF_LEX_WORD_ID;
+       if (!f->vargs_flag) {
+               for (i = 0; i < f->argv->size; i++) {
+                       arg       = f->argv->data[i];
+
+                       if (!strcmp(arg->w->text->data, "arguments"))
+                               break;
+               }
+
+               assert(0 == scf_vector_del(f->argv,        arg));
+               assert(0 == scf_vector_del(f->scope->vars, arg));
+
+               assert(2 == arg->refs);
+               arg->refs = 1;
+
+               scf_variable_free(arg);
+               arg = NULL;
+       }
+
+       for (i = fd->start_word; i < words->size; i++) {
+               w  = words->data[i];
+
+               if (!f->src_code) {
+                       f->src_code = scf_string_clone(w->text);
+                       if (!f->src_code)
+                               return -ENOMEM;
+               } else {
+                       int ret = scf_string_cat_cstr_len(f->src_code, " ", 1);
+                       if (ret < 0)
+                               return ret;
+
+                       ret = scf_string_cat(f->src_code, w->text);
+                       if (ret < 0)
+                               return ret;
+               }
+       }
+
+       w = dfa->ops->pop_word(dfa);
        dfa->ops->push_word(dfa, w);
 
+       switch (w->type) {
+               case SCF_LEX_WORD_SEMICOLON:
+               case SCF_LEX_WORD_COMMA:
+               case SCF_LEX_WORD_LP:
+                       w = scf_lex_word_clone(f->node.w);
+                       if (!w)
+                               return -ENOMEM;
+                       w->type = SCF_LEX_WORD_ID;
+
+                       dfa->ops->push_word(dfa, w);
+                       break;
+               default:
+                       break;
+       };
+
        d->expr         = fd->parent_expr;
        fd->parent_expr = NULL;
        fd->parent_block = NULL;
@@ -281,12 +354,11 @@ static int _function_js_action_end(scf_dfa_t* dfa, scf_vector_t* words, void* da
 static int _dfa_init_module_function_js(scf_dfa_t* dfa)
 {
        SCF_DFA_MODULE_NODE(dfa, function_js, comma,    scf_dfa_is_comma,    _function_js_action_comma);
-       SCF_DFA_MODULE_NODE(dfa, function_js, vargs,    scf_dfa_is_vargs,    _function_js_action_vargs);
        SCF_DFA_MODULE_NODE(dfa, function_js, end,      scf_dfa_is_entry,    _function_js_action_end);
 
        SCF_DFA_MODULE_NODE(dfa, function_js, lp,       scf_dfa_is_lp,       _function_js_action_lp);
        SCF_DFA_MODULE_NODE(dfa, function_js, rp,       scf_dfa_is_rp,       _function_js_action_rp);
-       SCF_DFA_MODULE_NODE(dfa, function_js, func,     scf_dfa_is_func,     scf_dfa_action_next);
+       SCF_DFA_MODULE_NODE(dfa, function_js, func,     scf_dfa_is_func,     _function_js_action_func);
        SCF_DFA_MODULE_NODE(dfa, function_js, fname,    scf_dfa_is_identity, scf_dfa_action_next);
        SCF_DFA_MODULE_NODE(dfa, function_js, arg,      scf_dfa_is_identity, scf_dfa_action_next);
 
@@ -325,7 +397,6 @@ static int _dfa_fini_module_function_js(scf_dfa_t* dfa)
 static int _dfa_init_syntax_function_js(scf_dfa_t* dfa)
 {
        SCF_DFA_GET_MODULE_NODE(dfa, function_js, comma,     comma);
-       SCF_DFA_GET_MODULE_NODE(dfa, function_js, vargs,     vargs);
 
        SCF_DFA_GET_MODULE_NODE(dfa, function_js, lp,        lp);
        SCF_DFA_GET_MODULE_NODE(dfa, function_js, rp,        rp);
@@ -350,9 +421,6 @@ static int _dfa_init_syntax_function_js(scf_dfa_t* dfa)
        scf_dfa_node_add_child(comma,     arg);
        scf_dfa_node_add_child(arg,       rp);
 
-       scf_dfa_node_add_child(comma,     vargs);
-       scf_dfa_node_add_child(vargs,     rp);
-
        // function_js body
        scf_dfa_node_add_child(rp,        block);
 
index 67b9d8fa314e318a99ed6cbf789a99192b851261..2eb780848c257e8401de8e1370ea972630ccbd88 100644 (file)
@@ -6,7 +6,7 @@ extern scf_dfa_module_t  dfa_module_init_data;
 
 int scf_object_init(scf_ast_t* ast, scf_lex_word_t* w, scf_variable_t* var, scf_variable_t* obj, scf_vector_t* init_exprs);
 
-int _class_calculate_size(scf_dfa_t* dfa, scf_type_t* s);
+int _class_calculate_size(scf_type_t* s);
 
 int _expr_add_var(scf_parse_t* parse, dfa_data_t* d);
 
@@ -532,7 +532,7 @@ static int _data_action_rb(scf_dfa_t* dfa, scf_vector_t* words, void* data)
        if (ret < 0)
                goto error;
 
-       ret = _class_calculate_size(dfa, t);
+       ret = _class_calculate_size(t);
        if (ret < 0)
                goto error;
 
@@ -652,7 +652,7 @@ static int _data_action_rs(scf_dfa_t* dfa, scf_vector_t* words, void* data)
 
        scf_variable_free(obj);
        obj = NULL;
-       return SCF_DFA_NEXT_WORD;
+       return SCF_DFA_SWITCH_TO;
 }
 
 static int _dfa_init_module_init_data(scf_dfa_t* dfa)
@@ -662,8 +662,8 @@ static int _dfa_init_module_init_data(scf_dfa_t* dfa)
 
        SCF_DFA_MODULE_NODE(dfa, init_data, colon,    scf_dfa_is_colon,     scf_dfa_action_next);
        SCF_DFA_MODULE_NODE(dfa, init_data, comma,    scf_dfa_is_comma,     _data_action_comma);
-       SCF_DFA_MODULE_NODE(dfa, init_data, func,     scf_dfa_is_func,      _data_action_func);
-       SCF_DFA_MODULE_NODE(dfa, init_data, func_end, scf_dfa_is_entry,     _data_action_func_end);
+//     SCF_DFA_MODULE_NODE(dfa, init_data, func,     scf_dfa_is_func,      _data_action_func);
+//     SCF_DFA_MODULE_NODE(dfa, init_data, func_end, scf_dfa_is_entry,     _data_action_func_end);
 
        SCF_DFA_MODULE_NODE(dfa, init_data, lb,       scf_dfa_is_lb,        _data_action_lb);
        SCF_DFA_MODULE_NODE(dfa, init_data, rb,       scf_dfa_is_rb,        _data_action_rb);
@@ -692,8 +692,8 @@ static int _dfa_init_syntax_init_data(scf_dfa_t* dfa)
        SCF_DFA_GET_MODULE_NODE(dfa, init_data,   comma,     comma);
        SCF_DFA_GET_MODULE_NODE(dfa, init_data,   colon,     colon);
        SCF_DFA_GET_MODULE_NODE(dfa, init_data,   member,    member);
-       SCF_DFA_GET_MODULE_NODE(dfa, init_data,   func,      func);
-       SCF_DFA_GET_MODULE_NODE(dfa, init_data,   func_end,  func_end);
+//     SCF_DFA_GET_MODULE_NODE(dfa, init_data,   func,      func);
+//     SCF_DFA_GET_MODULE_NODE(dfa, init_data,   func_end,  func_end);
 
        SCF_DFA_GET_MODULE_NODE(dfa, init_data,   lb,        lb);
        SCF_DFA_GET_MODULE_NODE(dfa, init_data,   rb,        rb);
@@ -727,12 +727,12 @@ static int _dfa_init_syntax_init_data(scf_dfa_t* dfa)
        scf_dfa_node_add_child(lb,        member);
        scf_dfa_node_add_child(member,    colon);
 
-       // 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);
+//     // 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);
 
        scf_dfa_node_add_child(colon,     expr);
        scf_dfa_node_add_child(expr,      comma);
index fa22c3a29a531a00421045e2afe0b35e4a6c2244..331236ae727e3d755456d5164f7f3eb80108250e 100644 (file)
@@ -17,6 +17,9 @@ typedef struct {
 
 } dfa_switch_data_t;
 
+int _expr_add_var(scf_parse_t* parse, dfa_data_t* d);
+
+
 static int _switch_is_end(scf_dfa_t* dfa, void* word)
 {
        return 1;
@@ -58,7 +61,7 @@ static int _switch_action_lp(scf_dfa_t* dfa, scf_vector_t* words, void* data)
        dfa_data_t*   d     = data;
 
        assert(!d->expr);
-       d->expr_local_flag = 1;
+       d->expr_local_flag++;
 
        SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "switch_rp"),      SCF_DFA_HOOK_POST);
        SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "switch_lp_stat"), SCF_DFA_HOOK_POST);
@@ -99,7 +102,7 @@ static int _switch_action_rp(scf_dfa_t* dfa, scf_vector_t* words, void* data)
 
                scf_node_add_child(sd->_switch, d->expr);
                d->expr = NULL;
-               d->expr_local_flag = 0;
+               assert(--d->expr_local_flag >= 0);
 
                SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "switch_end"), SCF_DFA_HOOK_END);
 
@@ -121,7 +124,7 @@ static int _switch_action_case(scf_dfa_t* dfa, scf_vector_t* words, void* data)
        dfa_switch_data_t* sd    = scf_stack_top(s);
 
        assert(!d->expr);
-       d->expr_local_flag = 1;
+       d->expr_local_flag++;
 
        sd->child = scf_node_alloc(w, SCF_OP_CASE, NULL);
        if (!sd->child)
@@ -129,6 +132,8 @@ static int _switch_action_case(scf_dfa_t* dfa, scf_vector_t* words, void* data)
 
        scf_node_add_child((scf_node_t*)parse->ast->current_block, sd->child);
 
+       SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "switch_colon"), SCF_DFA_HOOK_PRE);
+
        return SCF_DFA_NEXT_WORD;
 }
 
@@ -165,9 +170,16 @@ static int _switch_action_colon(scf_dfa_t* dfa, scf_vector_t* words, void* data)
                        return SCF_DFA_ERROR;
                }
 
+               dfa_identity_t* id = scf_stack_top(d->current_identities);
+
+               if (id && id->identity) {
+                       if (_expr_add_var(parse, d) < 0)
+                               return SCF_DFA_ERROR;
+               }
+
                scf_node_add_child(sd->child, d->expr);
                d->expr = NULL;
-               d->expr_local_flag = 0;
+               assert(--d->expr_local_flag >= 0);
 
        } else {
                assert(SCF_OP_DEFAULT == sd->child->type);
index c4ce9ad075b9db1a99c600ffbbaef70718c38250..91aecdfb02972626d167d11bcc3c014d688ecf45 100644 (file)
@@ -1563,6 +1563,75 @@ static int __scf_op_semantic_call(scf_ast_t* ast, scf_function_t* f, void* data)
        return 0;
 }
 
+static int _semantic_add_this(scf_ast_t* ast, scf_function_t* f, scf_node_t* parent)
+{
+       scf_variable_t*  v;
+       scf_type_t*      t;
+       scf_node_t*      this;
+       scf_node_t*      p = parent->nodes[0];
+
+       while (p && SCF_OP_EXPR == p->type)
+               p = p->nodes[0];
+
+       if (SCF_OP_POINTER == p->type) {
+               assert(2 == p->nb_nodes);
+
+               this = p->nodes[0];
+       } else {
+               int 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;
+       scf_node_add_child(parent, this);
+
+       scf_logi("f: %s(), this: %p, p->type: %d\n", f->node.w->text->data, this, p->type);
+
+       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];
+                               p->nodes[1]->parent  = p->parent;
+                               break;
+                       }
+               }
+
+               p->nodes[0] = NULL;
+               p->nodes[1] = NULL;
+
+               scf_node_free(p);
+               p = NULL;
+       }
+
+       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;
+       }
+
+       return 0;
+}
+
 static int _scf_op_semantic_call(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* data)
 {
        assert(nb_nodes > 0);
@@ -1571,13 +1640,11 @@ 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_type_t*         t;
        scf_type_t*         Object = NULL;
        scf_node_t*         parent = nodes[0]->parent;
-       scf_node_t*         p;
-       scf_node_t*         this;
+       int i;
 
        d->pret = &nodes[0]->result;
        int ret = _scf_expr_calculate_internal(ast, nodes[0], d);
@@ -1607,74 +1674,48 @@ static int _scf_op_semantic_call(scf_ast_t* ast, scf_node_t** nodes, int nb_node
 
        f = v0->func_ptr;
 
-       if (f->member_flag) { // add 'this' pointer for member function
-               p = nodes[0];
-
-               while (p && SCF_OP_EXPR == p->type)
-                       p = p->nodes[0];
-
-               if (SCF_OP_POINTER == p->type) {
-                       assert(2 == p->nb_nodes);
-
-                       this = p->nodes[0];
-
-                       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;
-
-                       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;
-
-                       scf_node_free(p);
-                       p = NULL;
-               } else {
-                       ret = scf_ast_find_variable(&v, ast, "document");
+       if (f->member_flag) {
+               if (!parent->this_done) { // add 'this' pointer for member function
+                       ret = _semantic_add_this(ast, f, parent);
                        if (ret < 0)
                                return ret;
+                       parent->this_done = 1;
+               }
 
-                       if (nb_nodes < 2 || _scf_operand_get(nodes[1]) != v) {
-
-                               this = scf_node_alloc(NULL, v->type, v);
-                               if (!this)
-                                       return -ENOMEM;
+               if (!f->js_flag) {
+                       t   = NULL;
+                       v1  = _scf_operand_get(parent->nodes[1]);
 
-                               scf_node_add_child(parent, this);
+                       ret = scf_ast_find_type_type(&t, ast, v1->type);
+                       if (ret < 0)
+                               return ret;
 
-                               int i;
-                               for (i = parent->nb_nodes - 2; i >= 1; i--)
-                                       parent->nodes[i + 1] = parent->nodes[i];
-                               parent->nodes[1] = this;
+                       scf_vector_t* argv = scf_vector_alloc();
+                       if (!argv)
+                               return -ENOMEM;
 
-                               scf_logi("f: %s(), this: %p, p->type: %d\n", f->node.w->text->data, this, p->type);
+                       for (i = 1; i < parent->nb_nodes; i++) {
+                               ret = scf_vector_add(argv, _scf_operand_get(parent->nodes[i]));
+                               if (ret < 0) {
+                                       scf_vector_free(argv);
+                                       return ret;
+                               }
                        }
-               }
 
-               if (f->js_flag) {
-                       p = parent->nodes[0];
-                       while (p && SCF_OP_EXPR == p->type)
-                               p = p->nodes[0];
+                       scf_function_t* f2 = NULL;
 
-                       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;
+                       ret = _semantic_find_proper_function(ast, t, f->node.w->text->data, argv, &f2);
 
-                       scf_node_free_data(p);
+                       scf_vector_free(argv);
+                       argv = NULL;
+                       if (ret < 0) {
+                               scf_loge("function '%s()' of class '%s' not found\n", f->node.w->text->data, t->name->data);
+                               return ret;
+                       }
 
-                       p->type = SCF_FUNCTION_PTR;
-                       p->var  = v;
+                       v0 = _scf_operand_get(parent->nodes[0]);
+                       f = f2;
+                       v0->func_ptr = f2;
                }
        }
 
@@ -1684,16 +1725,29 @@ static int _scf_op_semantic_call(scf_ast_t* ast, scf_node_t** nodes, int nb_node
                                        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 == parent->nb_nodes - 2 && f->js_flag && !f->vargs_flag) {
+               scf_node_t* arguments = parent->nodes[2];
+
+               for (i = 3; i < parent->nb_nodes; i++)
+                       parent->nodes[i - 1] = parent->nodes[i];
+               parent->nodes[i - 1] = NULL;
+               parent->nb_nodes--;
+
+               assert(arguments->js_create);
+               arguments->js_create->_3ac_done = 1;
+
+               scf_node_free(arguments);
+               arguments = NULL;
+
        } 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, 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, parent->nb_nodes);
 
-       int i;
        for (i = 0; i < f->argv->size; i++) {
                v0 =        f->argv->data[i];
 
@@ -2785,6 +2839,63 @@ static int _semantic_multi_rets_assign(scf_ast_t* ast, scf_node_t** nodes, int n
        return 0;
 }
 
+static scf_variable_t* __object_func_ptr(scf_node_t* p)
+{
+       while (SCF_OP_EXPR == p->type)
+               p = p->nodes[0];
+
+       if (SCF_OP_ARRAY_INDEX == p->type || SCF_OP_POINTER == p->type) {
+               assert(2 == p->nb_nodes);
+
+               p = p->nodes[1];
+
+               while (SCF_OP_EXPR == p->type)
+                       p = p->nodes[0];
+       }
+
+       if (!scf_type_is_var(p->type))
+               return NULL;
+
+       if (p->var->js_var)
+               return p->var->js_var;
+       return p->var;
+}
+
+static scf_node_t* __object_func_src(scf_ast_t* ast, scf_function_t* f)
+{
+       scf_node_t*      node;
+       scf_type_t*      t = scf_block_find_type_type(ast->current_block, SCF_VAR_CHAR);
+       scf_variable_t*  v;
+       scf_lex_word_t*  w = scf_lex_word_clone(f->node.w);
+
+       if (!w)
+               return NULL;
+
+       int ret = scf_string_cat_cstr(w->text, "__cstr");
+       if (ret < 0) {
+               scf_lex_word_free(w);
+               return NULL;
+       }
+
+       v = SCF_VAR_ALLOC_BY_TYPE(w, t, 1, 1, NULL);
+       scf_lex_word_free(w);
+       w = NULL;
+       if (!v)
+               return NULL;
+
+       v->data.s = scf_string_clone(f->src_code);
+       if (!v->data.s) {
+               scf_variable_free(v);
+               return NULL;
+       }
+       v->const_literal_flag = 1;
+
+       node = scf_node_alloc(NULL, v->type, v);
+       scf_variable_free(v);
+       v = NULL;
+       return node;
+}
+
 static int _scf_op_semantic_assign(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* data)
 {
        assert(2 == nb_nodes);
@@ -2825,8 +2936,8 @@ static int _scf_op_semantic_assign(scf_ast_t* ast, scf_node_t** nodes, int nb_no
                return _semantic_multi_rets_assign(ast, nodes, nb_nodes, data);
        }
 
-       scf_variable_t* v0     = _scf_operand_get(nodes[0]);
-       scf_variable_t* v1     = _scf_operand_get(nodes[1]);
+       scf_variable_t* v0 = _scf_operand_get(nodes[0]);
+       scf_variable_t* v1 = _scf_operand_get(nodes[1]);
 
        assert(v0);
        assert(v1);
@@ -2898,22 +3009,52 @@ static int _scf_op_semantic_assign(scf_ast_t* ast, scf_node_t** nodes, int nb_no
                return -1;
        }
 
+       scf_type_t* t  = NULL;
+       scf_type_t* t1 = NULL;
+
+       int ret = scf_ast_find_type_type(&t, ast, v0->type);
+       if (ret < 0)
+               return ret;
+
+       if (!strcmp(t->name->data, "Object")) {
+               ret = scf_ast_find_type_type(&t1, ast, v1->type);
+               if (ret < 0)
+                       return ret;
+
+               scf_variable_t* pf0 = __object_func_ptr(nodes[0]);
+               scf_variable_t* pf1;
+
+               if (!strcmp(t1->name->data, "Object"))
+                       pf1 = __object_func_ptr(nodes[1]);
+               else
+                       pf1 = v1;
+
+               if (pf0 && pf1 && SCF_FUNCTION_PTR == pf1->type) {
+                       pf0->func_ptr = pf1->func_ptr;
+
+                       scf_logd("---- pf1: %s()\n", pf1->w->text->data);
+               }
+       }
+
        if (!scf_variable_same_type(v0, v1)) {
 
                if (scf_variable_is_struct_pointer(v0) && v1->w && strcmp(v1->w->text->data, "NULL")) {
 
-                       scf_type_t*     t = NULL;
-                       int ret = scf_ast_find_type_type(&t, ast, v0->type);
-                       if (ret < 0)
-                               return ret;
-                       assert(t);
+                       if (!strcmp(t->name->data, "Object") && SCF_FUNCTION_PTR == v1->type) {
+                               scf_node_t* node = __object_func_src(ast, v1->func_ptr);
+                               if (!node)
+                                       return -ENOMEM;
+
+                               scf_node_free(nodes[1]);
+                               nodes[1] = node;
+                               node->parent = parent;
 
-                       if (!strcmp(t->name->data, "Object") && SCF_FUNCTION_PTR == v1->type)
-                               v0->func_ptr = v1->func_ptr;
+                               v1 = _scf_operand_get(nodes[1]);
+                       }
 
                        if (scf_scope_find_function(t->scope, "__init")) {
 
-                               int ret = _semantic_do_create(ast, nodes, nb_nodes, d);
+                               ret = _semantic_do_create(ast, nodes, nb_nodes, d);
                                if (0 == ret)
                                        return 0;
 
@@ -2931,15 +3072,15 @@ static int _scf_op_semantic_assign(scf_ast_t* ast, scf_node_t** nodes, int nb_no
                        return -1;
                }
 
-               int ret = _semantic_add_type_cast(ast, &nodes[1], v0, nodes[1]);
+               ret = _semantic_add_type_cast(ast, &nodes[1], v0, nodes[1]);
                if (ret < 0) {
                        scf_loge("add type cast failed\n");
                        return ret;
                }
        }
 
-       scf_type_t*     t = NULL;
-       int ret = scf_ast_find_type_type(&t, ast, v0->type);
+       t   = NULL;
+       ret = scf_ast_find_type_type(&t, ast, v0->type);
        if (ret < 0)
                return ret;
 
index aa89b4c976c83c02aeca8bb73461d592dd7c89b1..e7c0cb79d2d915dbafcc313f3a0b8e511a14464f 100644 (file)
@@ -83,8 +83,7 @@ struct dfa_data_s {
        scf_lex_word_t*      current_assign_w;
        scf_lex_word_t*      current_async_w;
 
-       scf_type_t*              root_struct;
-       scf_type_t*              current_struct;
+       scf_block_t*         parent_block;
 
        scf_node_t*          current_node;
 
index fade2746baf5d336b14d3f8db560bfe03a42bdc7..04d6fc59e2a839eb5fd837d0fb7ad46b3f916525 100644 (file)
@@ -156,6 +156,8 @@ CFILES += ../js/core/scf_pointer_alias.c
 CFILES += ../js/core/scf_optimizer.c
 CFILES += ../js/core/scf_optimizer_dag.c
 CFILES += ../js/core/scf_optimizer_inline.c
+CFILES += ../js/core/scf_optimizer_js_array.c
+CFILES += ../js/core/scf_optimizer_js_call.c
 CFILES += ../js/core/scf_optimizer_split_call.c
 CFILES += ../js/core/scf_optimizer_call.c
 CFILES += ../js/core/scf_optimizer_common_expr.c