js: simple Object Model ok
authoryu.dongliang <18588496441@163.com>
Wed, 13 Aug 2025 05:15:46 +0000 (13:15 +0800)
committeryu.dongliang <18588496441@163.com>
Wed, 13 Aug 2025 05:15:46 +0000 (13:15 +0800)
33 files changed:
examples/js.html
html/Makefile
js/abc_libjs.so
js/core/scf_ast.c
js/core/scf_ast.h
js/core/scf_dag.c
js/core/scf_lex_word.h
js/core/scf_optimizer_auto_gc.c
js/core/scf_pointer_alias.c
js/core/scf_scope.c
js/core/scf_type.h
js/core/scf_variable.c
js/core/scf_variable.h
js/doc.c
js/elf/scf_elf_x64_so.c
js/lex/scf_lex.c
js/lib/scf_capi.c
js/lib/x64/scf_object.o
js/native/x64/scf_x64_bb_color.c
js/native/x64/scf_x64_inst.c
js/native/x64/scf_x64_reg.c
js/native/x64/scf_x64_reg.h
js/parse/main.c
js/parse/scf_dfa_expr.c
js/parse/scf_dfa_function_js.c [new file with mode: 0644]
js/parse/scf_dfa_init_data.c
js/parse/scf_dfa_parse.c
js/parse/scf_dfa_util.h
js/parse/scf_dfa_var.c
js/parse/scf_parse.c
js/parse/scf_parse.h
js/parse/scf_struct_array.c
ui/Makefile

index a37709d761450facf0da5ca0aff2465e1fe946e4..1c701f0c8c91f05255603ed83e578c833874f5b5 100644 (file)
@@ -7,10 +7,16 @@
 <p>含有js的页面</p>
 
 <script>
-var obj = {
-       arr: [ {x: "1"}, {x: "2"} ],
+var a = [3.14, 2.71];
+
+var b = {
+       p: {
+               x:1.1,
+               y:2.1
+       },
+       z: 3.1,
 };
-document.write(obj.arr[1].x);
+document.write(a[1] + b.p.x + b.z);
 </script>
 
 </body>
index 59b84acd4f70bcb7a493860a033296d89dc09173..1d21c3604a87d42561ddbcc060cf8df31eab36c6 100644 (file)
@@ -147,6 +147,7 @@ CFILES += ../js/parse/scf_dfa_type.c
 CFILES += ../js/parse/scf_dfa_identity.c
 
 CFILES += ../js/parse/scf_dfa_function.c
+CFILES += ../js/parse/scf_dfa_function_js.c
 CFILES += ../js/parse/scf_dfa_operator.c
 CFILES += ../js/parse/scf_dfa_var.c
 
index 11e076095d1acac48e38c7f89f57f70c6d26cfdc..cb2894b91f8825c8ff490375a86190317ca0631c 100755 (executable)
Binary files a/js/abc_libjs.so and b/js/abc_libjs.so differ
index a85bc7f272efbcecfaff6bc4c863837c96b5b487..2e815bb4d7c20e2743038fbc07caa39a9ea31db8 100644 (file)
@@ -410,3 +410,75 @@ int scf_ast_find_type_type(scf_type_t** pt, scf_ast_t* ast, int type)
        return scf_ast_find_global_type_type(pt, ast, type);
 }
 
+int scf_ast_add_const_str(scf_ast_t* ast, scf_node_t* parent, scf_lex_word_t* w)
+{
+       scf_variable_t* v;
+       scf_lex_word_t* w2;
+       scf_type_t*     t = scf_block_find_type_type(ast->current_block, SCF_VAR_CHAR);
+       scf_node_t*     node;
+
+       w2 = scf_lex_word_clone(w);
+       if (!w2)
+               return -ENOMEM;
+
+       int ret = scf_string_cat_cstr(w2->text, "__cstr");
+       if (ret < 0) {
+               scf_lex_word_free(w2);
+               return ret;
+       }
+
+       v = SCF_VAR_ALLOC_BY_TYPE(w2, t, 1, 1, NULL);
+       scf_lex_word_free(w2);
+       w2 = NULL;
+       if (!v)
+               return -ENOMEM;
+       v->const_literal_flag = 1;
+
+       scf_logi("w->text: %s\n", w->text->data);
+       v->data.s = scf_string_clone(w->text);
+       if (!v->data.s) {
+               scf_variable_free(v);
+               return -ENOMEM;
+       }
+
+       node = scf_node_alloc(NULL, v->type, v);
+       scf_variable_free(v);
+       v = NULL;
+       if (!node)
+               return -ENOMEM;
+
+       ret = scf_node_add_child(parent, node);
+       if (ret < 0) {
+               scf_node_free(node);
+               return ret;
+       }
+
+       return 0;
+}
+
+int scf_ast_add_const_var(scf_ast_t* ast, scf_node_t* parent, int type, const uint64_t u64)
+{
+       scf_variable_t* v;
+       scf_type_t*     t = scf_block_find_type_type(ast->current_block, type);
+       scf_node_t*     node;
+
+       v = SCF_VAR_ALLOC_BY_TYPE(NULL, t, 1, 0, NULL);
+       if (!v)
+               return -ENOMEM;
+       v->data.u64           = u64;
+       v->const_literal_flag = 1;
+
+       node = scf_node_alloc(NULL, v->type, v);
+       scf_variable_free(v);
+       v = NULL;
+       if (!node)
+               return -ENOMEM;
+
+       int ret = scf_node_add_child(parent, node);
+       if (ret < 0) {
+               scf_node_free(node);
+               return ret;
+       }
+
+       return 0;
+}
index 404c778b6b5a2ecb8edeecabe091639e1a54e71d..f05e72e16b7f70fe097a529b6d98326d22719db1 100644 (file)
@@ -101,5 +101,7 @@ int scf_ast_add_base_type(scf_ast_t* ast, scf_base_type_t* base_type);
 
 int scf_ast_add_file_block(scf_ast_t* ast, const char* path);
 
-#endif
+int scf_ast_add_const_str(scf_ast_t* ast, scf_node_t* parent, scf_lex_word_t* w);
+int scf_ast_add_const_var(scf_ast_t* ast, scf_node_t* parent, int type, const uint64_t u64);
 
+#endif
index 6290c18dfcebee3fc163afc730005c583cb9c45e..fb92226565d6fdaf839e82a54209d6c4b8617d1c 100644 (file)
@@ -280,7 +280,11 @@ void scf_dn_status_print(scf_dn_status_t* ds)
 
        if (ds->dag_node) {
                v = ds->dag_node->var;
-               printf("dn: v_%d_%d/%s ", v->w->line, v->w->pos, v->w->text->data);
+
+               if (v->w)
+                       printf("dn: v_%d_%d/%s ", v->w->line, v->w->pos, v->w->text->data);
+               else
+                       printf("dn: v_%#lx ", (uintptr_t)v & 0xffff);
 
                if (ds->dn_indexes) {
                        for (i = ds->dn_indexes->size - 1; i >= 0; i--) {
@@ -296,7 +300,10 @@ void scf_dn_status_print(scf_dn_status_t* ds)
 
        if (ds->alias) {
                v = ds->alias->var;
-               printf(" alias: v_%d_%d/%s ", v->w->line, v->w->pos, v->w->text->data);
+               if (v->w)
+                       printf(" alias: v_%d_%d/%s ", v->w->line, v->w->pos, v->w->text->data);
+               else
+                       printf(" alias: v_%#lx ", (uintptr_t)v & 0xffff);
 
                if (ds->alias_indexes) {
                        for (i = ds->alias_indexes->size - 1; i >= 0; i--) {
index b9addb63d9f0eac266611cfa87769d884112b8d7..7b2c10a6d81e59ce6a68c9fcfd1431bf3bcb1634 100644 (file)
@@ -148,6 +148,7 @@ enum scf_lex_words
 
        // class
        SCF_LEX_WORD_KEY_CLASS,     // class
+       SCF_LEX_WORD_KEY_FUNC,      // function
 
        SCF_LEX_WORD_KEY_CONST,     // const
        SCF_LEX_WORD_KEY_STATIC,    // static
index 822c25a1e7b0f07cab9f39a16f8321dd63f9de81..2b1ab068cd228a9266a5f5fb50f6b2d462456af8 100644 (file)
@@ -22,23 +22,50 @@ static int _find_ds_malloced(scf_basic_block_t* bb, void* data)
        return 0;
 }
 
-static int _find_dn_active(scf_basic_block_t* bb, void* data)
+static int __find_dn_active(scf_vector_t* dn_vec, scf_dag_node_t* dn)
 {
-       scf_dag_node_t* dn = data;
+       scf_dn_status_t* ds = NULL;
+       scf_dag_node_t*  dn2;
+       int i;
 
-       if (scf_vector_find(bb->dn_loads, data))
-               return 1;
+       for (i = 0; i < dn_vec->size; i++) {
+               dn2       = dn_vec->data[i];
 
-       if (scf_vector_find(bb->dn_reloads, data))
-               return 1;
+               if (dn2 == dn)
+                       return 1;
 
-       if (scf_vector_find(bb->entry_dn_actives, data))
-               return 1;
+               int ret = scf_ds_for_dn(&ds, dn2);
+               if (ret < 0)
+                       return ret;
+
+               if (ds->dag_node == dn) {
+                       scf_dn_status_free(ds);
+                       return 1;
+               }
+
+               scf_dn_status_free(ds);
+               ds = NULL;
+       }
 
-       scf_logd("bb: %p, dn: %s, 0\n", bb, dn->var->w->text->data);
        return 0;
 }
 
+static int _find_dn_active(scf_basic_block_t* bb, void* data)
+{
+       scf_dag_node_t*  dn = data;
+
+       int ret = __find_dn_active(bb->dn_loads, dn);
+       if (0 == ret) {
+               ret = __find_dn_active(bb->dn_reloads, dn);
+
+               if (0 == ret)
+                       ret = __find_dn_active(bb->entry_dn_actives, dn);
+       }
+
+       scf_logd("bb: %p, dn: %s, 0\n", bb, dn->var->w->text->data);
+       return ret;
+}
+
 static int _bb_find_ds_malloced(scf_basic_block_t* root, scf_list_t* bb_list_head, scf_dn_status_t* ds, scf_vector_t* results)
 {
        scf_basic_block_visit_flag(bb_list_head, 0);
@@ -1014,7 +1041,6 @@ static int _optimize_auto_gc(scf_ast_t* ast, scf_function_t* f, scf_vector_t* fu
                }
        }
 
-//     scf_basic_block_print_list(bb_list_head);
        return 0;
 }
 
index 2232ac77d5b59d2efc5f5f3ba002eaecb0e3e2ff..811de5d0962e5df160685d25cb87d3fd06237345 100644 (file)
@@ -1557,7 +1557,7 @@ int scf_pointer_alias(scf_vector_t* aliases, scf_dag_node_t* dn_alias, scf_3ac_c
                default:
                        if (dn_alias->var && dn_alias->var->w) {
                                v = dn_alias->var;
-                               scf_loge("type: %d, v_%d_%d/%s\n", dn_alias->type, v->w->line, v->w->pos, v->w->text->data);
+                               scf_loge("type: %d, v_%d_%d/%s/%#lx\n", dn_alias->type, v->w->line, v->w->pos, v->w->text->data, 0xffff & (uintptr_t)dn_alias->var);
                        } else
                                scf_loge("type: %d, v_%#lx\n", dn_alias->type, 0xffff & (uintptr_t)dn_alias->var);
                        return -1;
index 8790ebe13acbba2b79b48f0bbc14da283f3fc905..9e7612f612725941d933cf88236878e0204e69d3 100644 (file)
@@ -42,6 +42,9 @@ void scf_scope_push_var(scf_scope_t* scope, scf_variable_t* var)
 {
        assert(scope);
        assert(var);
+
+       var->js_index = scope->vars->size;
+
        scf_vector_add(scope->vars, var);
 }
 
index efb3a1592a4cc645f38666c55c9ea3bd538477d7..82aa8a9d9d4424fc555f58da1d0ba7f81e97f2f1 100644 (file)
@@ -36,6 +36,7 @@ struct scf_type_s {
        int                                     size;
        int                                     offset; // only used for member var of struct or class
 
+       scf_type_t*                     super;  // pointed to super  type extended by this
        scf_type_t*                     parent; // pointed to parent type includes this
 };
 
index 96197d20ae567ef7952ae62fd43e235ade2f0902..3c2fde5450115004f1d98474a69767cd2cb19d9d 100644 (file)
@@ -100,6 +100,9 @@ scf_variable_t*     scf_variable_alloc(scf_lex_word_t* w, scf_type_t* t)
        v->refs = 1;
        v->type = t->type;
 
+       v->js_type  = -1;
+       v->js_index = -1;
+
        v->const_flag  = t->node.const_flag;
        v->nb_pointers = t->nb_pointers;
        v->func_ptr    = t->func_ptr;
index 89e8b19053828ff18b07deaa554c5afd0c14dd1a..1e4ae3d7c0732ec2fe0c939b97d1d9a48b2e9d8d 100644 (file)
@@ -16,6 +16,9 @@ struct scf_variable_s {
        int                                     type;   // type
        scf_lex_word_t*         w;              // lex word
 
+       int                 js_type;
+       int                 js_index;
+
        int                 nb_lbs; // number of '{}' when parse js object
        int                 nb_rbs;
 
index a575256b2320e96cf8e69160071e7cb5adb787eb..849a9db5030549a26a284d0fe23541ae8a99d77e 100644 (file)
--- a/js/doc.c
+++ b/js/doc.c
@@ -1,4 +1,107 @@
-int printf(const char* fmt, ...);
+#include"../js/lib/scf_capi.c"
+
+struct Object
+{
+       int       type;
+       int       n_members;
+       Object**  members;
+       char*     name;
+// p.x --> p.members[x]
+       char*     str;
+       double    d;
+
+       int __init(Object* this, double d)
+       {
+               this->d = d;
+               return 0;
+       }
+
+       int __init(Object* this, const char* name, int n_members)
+       {
+               printf("this: %p, name: %s\n", this, name);
+               int len = strlen(name);
+
+               this->name = scf__auto_malloc(len + 1);
+               if (!this->name)
+                       return -1;
+               memcpy(this->name, name, len + 1);
+
+               this->n_members = n_members;
+
+               if (n_members > 0) {
+                       this->members = scf__auto_malloc(sizeof(Object*) * n_members);
+                       if (!this->members)
+                               return -1;
+               }
+
+               printf("\n");
+               return 0;
+       }
+
+       int __init(Object* this, const char* name, int n_members, double d)
+       {
+               printf("this: %p, name: %s\n", this, name);
+               int len = strlen(name);
+
+               this->name = scf__auto_malloc(len + 1);
+               if (!this->name)
+                       return -1;
+               memcpy(this->name, name, len + 1);
+
+               this->n_members = n_members;
+
+               if (n_members > 0) {
+                       this->members = scf__auto_malloc(sizeof(Object*) * n_members);
+                       if (!this->members)
+                               return -1;
+               }
+
+               this->d = d;
+
+               printf("this: %p, this->d: %lg, d: %lg\n", this, this->d, d);
+               return 0;
+       }
+
+       const char* toString(Object* this)
+       {
+               char* s = scf__auto_malloc(128);
+               if (!s)
+                       return NULL;
+
+               snprintf(s, 127, "%lg", this->d);
+               return s;
+       }
+
+       Object* operator+(Object* this, Object* that)
+       {
+               Object* res = create Object(this->d + that->d);
+               return res;
+       }
+
+       void __release(Object* this)
+       {
+               if (this->members) {
+                       int i;
+                       for (i = 0; i < this->n_members; i++) {
+                               if (this->members[i]) {
+                                       this->members[i].__release();
+
+                                       scf__auto_freep(&this->members[i], NULL);
+                               }
+                       }
+
+                       scf__auto_freep(&this->members, NULL);
+               }
+
+               if (this->name)
+                       scf__auto_freep(&this->name, NULL);
+
+               if (this->str)
+                       scf__auto_freep(&this->str, NULL);
+
+//             printf("\n");
+       }
+};
 
 struct HTML;
 
@@ -6,8 +109,9 @@ int abc_html_write(HTML* html, const char* s);
 
 struct HTML
 {
-       void write(HTML* this, const char* s)
+       void write(HTML* this, Object* obj)
        {
+               char* s = obj.toString();
                abc_html_write(this, s);
        }
 };
index 236e9a4648b3271f10a5e5e803898a07491f1258..46b1df7543df77ec0ad70bf66d627c8cb814d006 100644 (file)
@@ -170,10 +170,7 @@ static int _x64_elf_add_gnu_hash(elf_native_t* x64, elf_section_t** ps)
 #define HASH_BUCKETS 3
 #define HASH_BLOOMS  1
 
-       int n_syms = x64->dynsyms->size;
-
-       if (x64->dyn_relas)
-               n_syms -= x64->dyn_relas->size;
+       int n_syms = x64->dynsyms->size - x64->n_plts;
 
        int len = sizeof(uint32_t) * 4 + sizeof(uint64_t) * HASH_BLOOMS
                                           + sizeof(uint32_t) * HASH_BUCKETS
@@ -833,12 +830,9 @@ int __x64_so_add_dyn(elf_native_t* x64, const char* sysroot)
        scf_string_t* str = scf_string_alloc();
 
        char c = '\0';
-       int  j = 0;
+       int  j = x64->n_plts;
        int  i;
 
-       if (x64->dyn_relas)
-               j = x64->dyn_relas->size;
-
        scf_string_cat_cstr_len(str, &c, 1);
 
        for (i = 0; i < x64->dynsyms->size; i++) {
@@ -919,7 +913,7 @@ int __x64_so_add_dyn(elf_native_t* x64, const char* sysroot)
                dyns[i + 8].d_tag = DT_JMPREL;
 
                dyns[i + 5].d_un.d_ptr = (uintptr_t)x64->got_plt;
-               dyns[i + 6].d_un.d_ptr = sizeof(Elf64_Rela);
+               dyns[i + 6].d_un.d_ptr = x64->rela_plt->data_len;
                dyns[i + 7].d_un.d_ptr = DT_RELA;
                dyns[i + 8].d_un.d_ptr = (uintptr_t)x64->rela_plt;
 
index a62e8a84e2dafda832dda561c052efd93f1ebf7c..a9b9e565aead7c25ca06bc9c88466031a6429e29 100644 (file)
@@ -80,6 +80,7 @@ static scf_key_word_t  key_words[] =
        {"union",     SCF_LEX_WORD_KEY_UNION},
        {"struct",    SCF_LEX_WORD_KEY_STRUCT},
        {"var",       SCF_LEX_WORD_KEY_VAR},
+       {"function",  SCF_LEX_WORD_KEY_FUNC},
 };
 
 static scf_escape_char_t  escape_chars[] =
index 384b9576e9e3ff8498ca2d4654a4859c4ebd6323..759b34d50dd2bf851b244f61751c82bd294356cd 100644 (file)
@@ -1,5 +1,6 @@
 
 int   printf(const char* fmt, ...);
+int   snprintf(char* buf, uintptr_t size, const char* fmt, ...);
 
 int   rand();
 void  srand(uint32_t seed);
index 00fd5253109c65072c6564ed60a497bb9540a1cc..86e2a9f712e93bda81c0ce0abe0440bf1d4d5e1a 100644 (file)
Binary files a/js/lib/x64/scf_object.o and b/js/lib/x64/scf_object.o differ
index af9d9461f34fe5789b7d532fae7827ea4dde9db7..2f9eefa9ff712b3c5e146b5f429531fa843f3408 100644 (file)
@@ -428,8 +428,8 @@ int x64_load_bb_colors2(scf_basic_block_t* bb, scf_bb_group_t* bbg, scf_function
                for (j = 0; j < bb->prevs->size; j++) {
                        prev      = bb->prevs->data[j];
 
-                       if (!scf_vector_find(bbg->body, prev))
-                               continue;
+//                     if (!scf_vector_find(bbg->body, prev))
+//                             continue;
 
                        for (k = 0; k < prev->dn_colors_exit->size; k++) {
                                ds2       = prev->dn_colors_exit->data[k];
@@ -438,7 +438,8 @@ int x64_load_bb_colors2(scf_basic_block_t* bb, scf_bb_group_t* bbg, scf_function
                                        break;
                        }
 
-                       assert(k < prev->dn_colors_exit->size);
+                       if (k >= prev->dn_colors_exit->size)
+                               break;
 
                        if (0 == first) {
                                first      = 1;
@@ -452,12 +453,11 @@ int x64_load_bb_colors2(scf_basic_block_t* bb, scf_bb_group_t* bbg, scf_function
                }
 
                if (j < bb->prevs->size) {
-
                        for (j = 0; j < bb->prevs->size; j++) {
                                prev      = bb->prevs->data[j];
 
-                               if (!scf_vector_find(bbg->body, prev))
-                                       continue;
+                       //      if (!scf_vector_find(bbg->body, prev))
+                       //              continue;
 
                                for (k = 0; k < prev->dn_colors_exit->size; k++) {
                                        ds2       = prev->dn_colors_exit->data[k];
@@ -466,7 +466,8 @@ int x64_load_bb_colors2(scf_basic_block_t* bb, scf_bb_group_t* bbg, scf_function
                                                break;
                                }
 
-                               assert(k < prev->dn_colors_exit->size);
+                               if (k >= prev->dn_colors_exit->size)
+                                       continue;
 
                                if (x64_bb_save_dn2(ds2->color, dn, prev, f) < 0) {
                                        scf_loge("\n");
index baad56d49d5d70caf247ff046be8ce525a1b5462..985438098bc5046025323f5501642a2cb8c78137 100644 (file)
@@ -1049,7 +1049,7 @@ static int _x64_inst_array_index(scf_native_t* ctx, scf_3ac_code_t* c, int lea_f
                return ret;
        }
 
-       if (vb->nb_dimentions > 1 || vb->type >= SCF_STRUCT || lea_flag) {
+       if (vb->nb_dimentions > 1 || (vb->type >= SCF_STRUCT && 0 == vb->nb_pointers) || lea_flag) {
                OpCode = x64_find_OpCode(SCF_X64_LEA, rd->bytes, rd->bytes, SCF_X64_E2G);
 
        } else {
index 331d25d99b885677cff09110932616930a7a61a8..b21cb3a49ced5006e46331ad668aefce620e27e2 100644 (file)
@@ -207,18 +207,21 @@ void x64_registers_print()
        }
 }
 
-int x64_caller_save_regs(scf_3ac_code_t* c, uint32_t* regs, int nb_regs, int stack_size, scf_register_t** saved_regs)
+int x64_caller_save_regs(scf_3ac_code_t* c, const char* regs[], int nb_regs, int stack_size, scf_register_t** saved_regs)
 {
        scf_basic_block_t*  bb = c->basic_block;
        scf_dag_node_t*     dn;
 
        scf_instruction_t*  inst;
-       scf_x64_OpCode_t*   push = x64_find_OpCode(SCF_X64_PUSH, 8,8, SCF_X64_G);
-       scf_x64_OpCode_t*   mov  = x64_find_OpCode(SCF_X64_MOV,  8,8, SCF_X64_G2E);
-       scf_register_t*     rsp  = x64_find_register("rsp");
+       scf_x64_OpCode_t*   push  = x64_find_OpCode(SCF_X64_PUSH,  8,8, SCF_X64_G);
+       scf_x64_OpCode_t*   movsd = x64_find_OpCode(SCF_X64_MOVSD, 8,8, SCF_X64_G2E);
+       scf_x64_OpCode_t*   mov   = x64_find_OpCode(SCF_X64_MOV,   8,8, SCF_X64_G2E);
+       scf_x64_OpCode_t*   sub   = x64_find_OpCode(SCF_X64_SUB,   4,4, SCF_X64_I2E);
+       scf_register_t*     rsp   = x64_find_register("rsp");
        scf_register_t*     r;
        scf_register_t*     r2;
 
+       uint32_t imm = 8;
        int i;
        int j;
        int k;
@@ -226,7 +229,7 @@ int x64_caller_save_regs(scf_3ac_code_t* c, uint32_t* regs, int nb_regs, int sta
        int n    = 0;
 
        for (j = 0; j < nb_regs; j++) {
-               r2 = x64_find_register_type_id_bytes(0, regs[j], 8);
+               r2 = x64_find_register(regs[j]);
 
                for (i = 0; i < sizeof(x64_registers) / sizeof(x64_registers[0]); i++) {
                        r  = &(x64_registers[i]);
@@ -263,10 +266,21 @@ int x64_caller_save_regs(scf_3ac_code_t* c, uint32_t* regs, int nb_regs, int sta
                if (i == sizeof(x64_registers) / sizeof(x64_registers[0]))
                        continue;
 
-               if (stack_size > 0)
-                       inst = x64_make_inst_G2P(mov, rsp, size + stack_size, r2);
-               else
-                       inst = x64_make_inst_G(push, r2);
+               if (X64_COLOR_TYPE(r2->color)) {
+                       if (stack_size > 0)
+                               inst = x64_make_inst_G2P(movsd, rsp, size + stack_size, r2);
+                       else {
+                               inst = x64_make_inst_I2E(sub, rsp, (uint8_t*)&imm, 4);
+                               X64_INST_ADD_CHECK(c->instructions, inst);
+
+                               inst = x64_make_inst_G2P(movsd, rsp, 0, r2);
+                       }
+               } else {
+                       if (stack_size > 0)
+                               inst = x64_make_inst_G2P(mov, rsp, size + stack_size, r2);
+                       else
+                               inst = x64_make_inst_G(push, r2);
+               }
                X64_INST_ADD_CHECK(c->instructions, inst);
 
                saved_regs[n++] = r2;
@@ -276,10 +290,21 @@ int x64_caller_save_regs(scf_3ac_code_t* c, uint32_t* regs, int nb_regs, int sta
        if (size & 0xf) {
                r2 = saved_regs[n - 1];
 
-               if (stack_size > 0)
-                       inst = x64_make_inst_G2P(mov, rsp, size + stack_size, r2);
-               else
-                       inst = x64_make_inst_G(push, r2);
+               if (X64_COLOR_TYPE(r2->color)) {
+                       if (stack_size > 0)
+                               inst = x64_make_inst_G2P(movsd, rsp, size + stack_size, r2);
+                       else {
+                               inst = x64_make_inst_I2E(sub, rsp, (uint8_t*)&imm, 4);
+                               X64_INST_ADD_CHECK(c->instructions, inst);
+
+                               inst = x64_make_inst_G2P(movsd, rsp, 0, r2);
+                       }
+               } else {
+                       if (stack_size > 0)
+                               inst = x64_make_inst_G2P(mov, rsp, size + stack_size, r2);
+                       else
+                               inst = x64_make_inst_G(push, r2);
+               }
                X64_INST_ADD_CHECK(c->instructions, inst);
 
                saved_regs[n++] = r2;
@@ -297,53 +322,19 @@ int x64_caller_save_regs(scf_3ac_code_t* c, uint32_t* regs, int nb_regs, int sta
        return size;
 }
 
-int x64_push_regs(scf_vector_t* instructions, uint32_t* regs, int nb_regs)
-{
-       int i;
-       int j;
-       scf_register_t* r;
-       scf_register_t* r2;
-       scf_instruction_t*  inst;
-       scf_x64_OpCode_t*   push = x64_find_OpCode(SCF_X64_PUSH, 8,8, SCF_X64_G);
-
-       for (j = 0; j < nb_regs; j++) {
-               r2 = x64_find_register_type_id_bytes(0, regs[j], 8);
-
-               for (i = 0; i < sizeof(x64_registers) / sizeof(x64_registers[0]); i++) {
-                       r  = &(x64_registers[i]);
-
-                       if (!X64_COLOR_TYPE(r->color) && (SCF_X64_REG_RSP == r->id || SCF_X64_REG_RBP == r->id))
-                               continue;
-
-                       if (0 == r->dag_nodes->size)
-                               continue;
-
-                       if (X64_COLOR_CONFLICT(r2->color, r->color))
-                               break;
-               }
-
-               if (i == sizeof(x64_registers) / sizeof(x64_registers[0]))
-                       continue;
-
-               inst = x64_make_inst_G(push, r2);
-               X64_INST_ADD_CHECK(instructions, inst);
-       }
-       return 0;
-}
-
 int x64_pop_regs(scf_vector_t* instructions, scf_register_t** regs, int nb_regs, scf_register_t** updated_regs, int nb_updated)
 {
-       int i;
-       int j;
-
-       scf_register_t* rsp = x64_find_register("rsp");
-       scf_register_t* r;
-       scf_register_t* r2;
+       scf_register_t*     rsp = x64_find_register("rsp");
+       scf_register_t*     r;
+       scf_register_t*     r2;
        scf_instruction_t*  inst;
-       scf_x64_OpCode_t*   pop = x64_find_OpCode(SCF_X64_POP, 8, 8, SCF_X64_G);
-       scf_x64_OpCode_t*   add = x64_find_OpCode(SCF_X64_ADD, 4, 4, SCF_X64_I2E);
+       scf_x64_OpCode_t*   movsd = x64_find_OpCode(SCF_X64_MOVSD, 8, 8, SCF_X64_E2G);
+       scf_x64_OpCode_t*   pop   = x64_find_OpCode(SCF_X64_POP,   8, 8, SCF_X64_G);
+       scf_x64_OpCode_t*   add   = x64_find_OpCode(SCF_X64_ADD,   4, 4, SCF_X64_I2E);
 
        uint32_t imm = 8;
+       int i;
+       int j;
 
        for (j = nb_regs - 1; j >= 0; j--) {
                r2 = regs[j];
@@ -373,7 +364,13 @@ int x64_pop_regs(scf_vector_t* instructions, scf_register_t** regs, int nb_regs,
                }
 
                if (i == nb_updated) {
-                       inst = x64_make_inst_G(pop, r2);
+                       if (X64_COLOR_TYPE(r2->color)) {
+                               inst = x64_make_inst_P2G(movsd, r2, rsp, 0);
+                               X64_INST_ADD_CHECK(instructions, inst);
+
+                               inst = x64_make_inst_I2E(add, rsp, (uint8_t*)&imm, 4);
+                       } else
+                               inst = x64_make_inst_G(pop, r2);
                        X64_INST_ADD_CHECK(instructions, inst);
                } else {
                        inst = x64_make_inst_I2E(add, rsp, (uint8_t*)&imm, 4);
@@ -679,7 +676,7 @@ int x64_overflow_reg2(scf_register_t* r, scf_dag_node_t* dn, scf_3ac_code_t* c,
 int x64_reg_used(scf_register_t* r, scf_dag_node_t* dn)
 {
        scf_register_t* r2;
-       scf_dag_node_t*     dn2;
+       scf_dag_node_t* dn2;
 
        int i;
        int j;
@@ -695,7 +692,7 @@ int x64_reg_used(scf_register_t* r, scf_dag_node_t* dn)
                        continue;
 
                for (j  = 0; j < r2->dag_nodes->size; j++) {
-                       dn2 = r2->dag_nodes->data[j];
+                       dn2 =        r2->dag_nodes->data[j];
 
                        if (dn2 != dn)
                                return 1;
@@ -745,6 +742,8 @@ scf_register_t* x64_select_overflowed_reg(scf_dag_node_t* dn, scf_3ac_code_t* c)
        int i;
        int j;
 
+       scf_logi("bytes: %d\n", bytes);
+
        assert(c->rcg);
 
        ret = x64_rcg_find_node(&gn, c->rcg, dn, NULL);
@@ -1358,9 +1357,7 @@ int x64_push_callee_regs(scf_3ac_code_t* c, scf_function_t* f)
        int j;
 
        for (i = 0; i < X64_ABI_CALLEE_SAVES_NB; i++) {
-
-               j  =  x64_abi_callee_saves[i];
-               r  =  x64_find_register_type_id_bytes(0, j, 8);
+               r  =  x64_find_register(x64_abi_callee_saves[i]);
 
                for (j = 0; j < N; j++) {
                        r2 = &(x64_registers[j]);
@@ -1397,9 +1394,7 @@ int x64_pop_callee_regs(scf_3ac_code_t* c, scf_function_t* f)
        f->callee_saved_size = 0;
 
        for (i = X64_ABI_CALLEE_SAVES_NB - 1; i >= 0; i--) {
-
-               j  = x64_abi_callee_saves[i];
-               r  = x64_find_register_type_id_bytes(0, j, 8);
+               r  = x64_find_register(x64_abi_callee_saves[i]);
 
                for (j = 0; j < N; j++) {
                        r2 = &(x64_registers[j]);
index 790ce54961d727bb4a82b9d6dda9af948f00ebee..40c5967771b5a90a2e3178d900559814df91a874 100644 (file)
@@ -65,27 +65,36 @@ static uint32_t x64_abi_ret_regs[] =
 };
 #define X64_ABI_RET_NB (sizeof(x64_abi_ret_regs) / sizeof(x64_abi_ret_regs[0]))
 
-static uint32_t x64_abi_caller_saves[] =
+static const char* x64_abi_caller_saves[] =
 {
-       SCF_X64_REG_RAX,
-       SCF_X64_REG_RCX,
-       SCF_X64_REG_RDX,
-       SCF_X64_REG_RSI,
-       SCF_X64_REG_RDI,
-       SCF_X64_REG_R8,
-       SCF_X64_REG_R9,
-       SCF_X64_REG_R10,
-       SCF_X64_REG_R11,
+       "rax",
+       "rcx",
+       "rdx",
+       "rsi",
+       "rdi",
+       "r8",
+       "r9",
+       "r10",
+       "r11",
+
+       "xmm0",
+       "xmm1",
+       "xmm2",
+       "xmm3",
+       "xmm4",
+       "xmm5",
+       "xmm6",
+       "xmm7",
 };
 #define X64_ABI_CALLER_SAVES_NB (sizeof(x64_abi_caller_saves) / sizeof(x64_abi_caller_saves[0]))
 
-static uint32_t x64_abi_callee_saves[] =
+static const char* x64_abi_callee_saves[] =
 {
-       SCF_X64_REG_RBX,
-       SCF_X64_REG_R12,
-       SCF_X64_REG_R13,
-       SCF_X64_REG_R14,
-       SCF_X64_REG_R15,
+       "rbx",
+       "r12",
+       "r13",
+       "r14",
+       "r15",
 };
 #define X64_ABI_CALLEE_SAVES_NB (sizeof(x64_abi_callee_saves) / sizeof(x64_abi_callee_saves[0]))
 
@@ -138,7 +147,7 @@ int                 x64_save_var2(scf_dag_node_t* dn, scf_register_t* r, scf_3ac
 int                 x64_push_regs(scf_vector_t* instructions, uint32_t* regs, int nb_regs);
 int                 x64_pop_regs (scf_vector_t* instructions, scf_register_t** regs, int nb_regs, scf_register_t** updated_regs, int nb_updated);
 
-int                 x64_caller_save_regs(scf_3ac_code_t* c, uint32_t* regs, int nb_regs, int stack_size, scf_register_t** saved_regs);
+int                 x64_caller_save_regs(scf_3ac_code_t* c, const char* regs[], int nb_regs, int stack_size, scf_register_t** saved_regs);
 
 int                 x64_push_callee_regs(scf_3ac_code_t* c, scf_function_t* f);
 int                 x64_pop_callee_regs (scf_3ac_code_t* c, scf_function_t* f);
index d262425d83fe1a54a9d895fa1d4a671162a0d7d0..d592dd3da942e5555b98e54ab5cc09b674960e5a 100644 (file)
@@ -5,7 +5,7 @@
 
 static char* __objs[] =
 {
-       "_start.o",
+//     "_start.o",
        "scf_object.o",
        "scf_atomic.o",
 };
@@ -101,13 +101,11 @@ int scf_parse_link(const char* exec, const char* obj, const char* libjs, const c
 
 #define MAIN_ADD_FILES(_objs, _sofiles, _arch) \
        do { \
-               if (!dyn) { \
-                       int ret = add_sys_files(objs, sysroot, _arch, _objs, sizeof(_objs) / sizeof(_objs[0])); \
-                       if (ret < 0) \
-                               return ret; \
-               } \
-               \
-               int ret = add_sys_files(sofiles, sysroot, _arch, _sofiles, sizeof(_sofiles) / sizeof(_sofiles[0])); \
+               int ret; \
+               ret = add_sys_files(objs, sysroot, _arch, _objs, sizeof(_objs) / sizeof(_objs[0])); \
+               if (ret < 0) \
+                       return ret; \
+               ret = add_sys_files(sofiles, sysroot, _arch, _sofiles, sizeof(_sofiles) / sizeof(_sofiles[0])); \
                if (ret < 0) \
                    return ret; \
        } while (0)
index 6e9ea2826ac28d7c143c322a8c33424b8bd7c75e..949880bee86da8e2c911765f86256b2b1c0bee4a 100644 (file)
@@ -80,8 +80,10 @@ int _expr_add_var(scf_parse_t* parse, dfa_data_t* d)
 {
        expr_module_data_t* md   = d->module_datas[dfa_module_expr.index];
        scf_variable_t*     var  = NULL;
+       scf_variable_t*     v    = NULL;
        scf_node_t*         node = NULL;
        scf_type_t*         pt   = NULL;
+       scf_type_t*         t    = NULL;
        scf_function_t*     f    = NULL;
        dfa_identity_t*     id   = scf_stack_pop(d->current_identities);
        scf_lex_word_t*     w;
@@ -114,9 +116,25 @@ int _expr_add_var(scf_parse_t* parse, dfa_data_t* d)
                var->const_literal_flag = 1;
        }
 
-       scf_logi("var: %s, member_flag: %d, line: %d\n", var->w->text->data, var->member_flag, var->w->line);
+       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);
 
-       node = scf_node_alloc(w, var->type, var);
+       if (md->current_var
+                       && md->current_var->js_type >= 0
+                       && var->member_flag) {
+               scf_loge("var: %s, member_flag: %d, line: %d, pos: %d\n", var->w->text->data, var->member_flag, var->w->line, var->w->pos);
+
+               t = scf_block_find_type_type(parse->ast->current_block, SCF_VAR_INTPTR);
+               v = SCF_VAR_ALLOC_BY_TYPE(NULL, t, 1, 0, NULL);
+               if (!v)
+                       return -ENOMEM;
+               v->const_literal_flag = 1;
+               v->data.i64 = var->js_index;
+
+               node = scf_node_alloc(w, v->type, v);
+               scf_variable_free(v);
+               v = NULL;
+       } else
+               node = scf_node_alloc(w, var->type, var);
        if (!node)
                return -ENOMEM;
 
@@ -273,12 +291,14 @@ static int _expr_action_number(scf_dfa_t* dfa, scf_vector_t* words, void* data)
 
 static int _expr_action_op(scf_dfa_t* dfa, scf_vector_t* words, void* data, int nb_operands)
 {
-       scf_parse_t*     parse = dfa->priv;
-       dfa_data_t*      d     = data;
-       scf_lex_word_t*  w     = words->data[words->size - 1];
-
-       scf_operator_t*  op;
-       scf_node_t*      node;
+       scf_parse_t*         parse = dfa->priv;
+       dfa_data_t*          d     = data;
+       expr_module_data_t*  md    = d->module_datas[dfa_module_expr.index];
+       scf_lex_word_t*      w     = words->data[words->size - 1];
+       scf_variable_t*      v;
+       scf_operator_t*      op;
+       scf_node_t*          node;
+       scf_type_t*          t;
 
        op = scf_find_base_operator(w->text->data, nb_operands);
        if (!op) {
@@ -297,6 +317,44 @@ static int _expr_action_op(scf_dfa_t* dfa, scf_vector_t* words, void* data, int
                return SCF_DFA_ERROR;
        }
 
+       if (SCF_LEX_WORD_ARROW == w->type || SCF_LEX_WORD_DOT == w->type) {
+               if (md->current_var->js_type >= 0) {
+                       t = NULL;
+                       if (scf_ast_find_type(&t, parse->ast, "Object") < 0)
+                               return SCF_DFA_ERROR;
+
+                       v = scf_scope_find_variable(t->scope, "members");
+                       if (!v) {
+                               scf_logw("var 'members' not found in struct '%s'\n", t->name->data);
+                               return SCF_DFA_ERROR;
+                       }
+
+                       node = scf_node_alloc(NULL, v->type, v);
+                       if (!node)
+                               return SCF_DFA_ERROR;
+
+                       if (scf_expr_add_node(d->expr, node) < 0) {
+                               scf_node_free(node);
+                               return SCF_DFA_ERROR;
+                       }
+
+                       node = scf_node_alloc(NULL, SCF_OP_ARRAY_INDEX, NULL);
+                       if (!node)
+                               return SCF_DFA_ERROR;
+
+                       if (scf_expr_add_node(d->expr, node) < 0) {
+                               scf_node_free(node);
+                               return SCF_DFA_ERROR;
+                       }
+
+                       t = NULL;
+                       if (scf_ast_find_type_type(&t, parse->ast, md->current_var->js_type) < 0)
+                               return SCF_DFA_ERROR;
+
+                       parse->ast->current_block = (scf_block_t*)t;
+               }
+       }
+
        return SCF_DFA_NEXT_WORD;
 }
 
@@ -552,6 +610,10 @@ static int _expr_action_ls(scf_dfa_t* dfa, scf_vector_t* words, void* data)
        dfa_data_t*          d     = data;
        expr_module_data_t*  md    = d->module_datas[dfa_module_expr.index];
        dfa_identity_t*      id    = scf_stack_top(d->current_identities);
+       scf_operator_t*      op;
+       scf_variable_t*      v;
+       scf_type_t*          t;
+       scf_node_t*          node;
 
        if (id && id->identity) {
                if (_expr_add_var(parse, d) < 0) {
@@ -565,28 +627,56 @@ static int _expr_action_ls(scf_dfa_t* dfa, scf_vector_t* words, void* data)
                md->parent_block = NULL;
        }
 
-       scf_operator_t* op = scf_find_base_operator_by_type(SCF_OP_ARRAY_INDEX);
+       if (md->current_var->js_type >= 0) {
+               t = NULL;
+               if (scf_ast_find_type(&t, parse->ast, "Object") < 0)
+                       return SCF_DFA_ERROR;
+
+               v = scf_scope_find_variable(t->scope, "members");
+               if (!v) {
+                       scf_logw("var 'members' not found in struct '%s'\n", t->name->data);
+                       return SCF_DFA_ERROR;
+               }
+
+               node = scf_node_alloc(w, SCF_OP_POINTER, NULL);
+               if (!node)
+                       return SCF_DFA_ERROR;
+
+               if (scf_expr_add_node(d->expr, node) < 0) {
+                       scf_node_free(node);
+                       return SCF_DFA_ERROR;
+               }
+
+               node = scf_node_alloc(NULL, v->type, v);
+               if (!node)
+                       return SCF_DFA_ERROR;
+
+               if (scf_expr_add_node(d->expr, node) < 0) {
+                       scf_node_free(node);
+                       return SCF_DFA_ERROR;
+               }
+       }
+
+       op = scf_find_base_operator_by_type(SCF_OP_ARRAY_INDEX);
        assert(op);
 
-       scf_node_t* n = scf_node_alloc(w, op->type, NULL);
-       if (!n) {
+       node = scf_node_alloc(w, op->type, NULL);
+       if (!node) {
                scf_loge("node alloc error\n");
                return SCF_DFA_ERROR;
        }
-       n->op = op;
+       node->op = op;
 
-       scf_expr_add_node(d->expr, n);
+       scf_expr_add_node(d->expr, node);
 
        scf_stack_push(md->ls_exprs, d->expr);
 
-       scf_expr_t* index = scf_expr_alloc();
-       if (!index) {
+       d->expr = scf_expr_alloc();
+       if (!d->expr) {
                scf_loge("index expr alloc error\n");
                return SCF_DFA_ERROR;
        }
 
-       d->expr = index;
-
        return SCF_DFA_NEXT_WORD;
 }
 
diff --git a/js/parse/scf_dfa_function_js.c b/js/parse/scf_dfa_function_js.c
new file mode 100644 (file)
index 0000000..a32423d
--- /dev/null
@@ -0,0 +1,331 @@
+#include"scf_dfa.h"
+#include"scf_dfa_util.h"
+#include"scf_parse.h"
+
+extern scf_dfa_module_t dfa_module_function_js;
+
+typedef struct {
+
+       scf_block_t*     parent_block;
+
+} dfa_fun_data_t;
+
+int _function_js_add_function(scf_dfa_t* dfa, scf_lex_word_t* w, dfa_data_t* d)
+{
+       scf_parse_t*    parse = dfa->priv;
+       scf_ast_t*      ast   = parse->ast;
+       dfa_fun_data_t* fd    = d->module_datas[dfa_module_function_js.index];
+
+       scf_function_t* f;
+       scf_variable_t* v;
+       scf_block_t*    b;
+       scf_type_t*     t = NULL;
+
+       int ret = scf_ast_find_type(&t, ast, "Object");
+       if (ret < 0)
+               return ret;
+
+       b = ast->current_block;
+       while (b) {
+               if (b->node.type >= SCF_STRUCT)
+                       break;
+               b = (scf_block_t*)b->node.parent;
+       }
+
+       f = scf_function_alloc(w);
+       if (!f)
+               return SCF_DFA_ERROR;
+       f->member_flag = !!b;
+
+       scf_logi("function: %s,line:%d, member_flag: %d\n", f->node.w->text->data, f->node.w->line, f->member_flag);
+
+       v = SCF_VAR_ALLOC_BY_TYPE(w, t, 0, 1, NULL);
+       if (!v) {
+               scf_function_free(f);
+               return SCF_DFA_ERROR;
+       }
+
+       if (scf_vector_add(f->rets, v) < 0) {
+               scf_variable_free(v);
+               scf_function_free(f);
+               return SCF_DFA_ERROR;
+       }
+
+       scf_scope_push_function(ast->current_block->scope, f);
+
+       scf_node_add_child((scf_node_t*)ast->current_block, (scf_node_t*)f);
+
+       fd ->parent_block  = ast->current_block;
+       ast->current_block = (scf_block_t*)f;
+
+       d->current_function = f;
+
+       return SCF_DFA_NEXT_WORD;
+}
+
+int _function_js_add_arg(scf_ast_t* ast, scf_lex_word_t* w, dfa_data_t* d)
+{
+       scf_variable_t*  arg = NULL;
+       scf_type_t*      t   = NULL;
+
+       int ret = scf_ast_find_type(&t, ast, "Object");
+       if (ret < 0)
+               return ret;
+
+       arg = SCF_VAR_ALLOC_BY_TYPE(w, t, 0, 1, NULL);
+       if (!arg)
+               return SCF_DFA_ERROR;
+
+       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_vector_add(d->current_function->argv, arg);
+
+       arg->refs++;
+       arg->arg_flag   = 1;
+       arg->local_flag = 1;
+
+       d->argc++;
+
+       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;
+       dfa_data_t*      d     = data;
+       scf_lex_word_t*  w;
+
+       if (words->size < 2)
+               return SCF_DFA_ERROR;
+       w = words->data[words->size - 2];
+
+       if (!scf_lex_is_identity(w))
+               return SCF_DFA_ERROR;
+
+       if (_function_js_add_arg(parse->ast, w, d) < 0) {
+               scf_loge("function_js add arg failed\n");
+               return SCF_DFA_ERROR;
+       }
+
+       SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "function_js_comma"), SCF_DFA_HOOK_PRE);
+
+       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;
+       dfa_data_t*      d     = data;
+       dfa_fun_data_t*  fd    = d->module_datas[dfa_module_function_js.index];
+       scf_lex_word_t*  w;
+
+       if (words->size < 2)
+               return SCF_DFA_ERROR;
+       w = words->data[words->size - 2];
+
+       assert(!d->current_node);
+
+       d->current_var = NULL;
+
+       if (_function_js_add_function(dfa, w, d) < 0)
+               return SCF_DFA_ERROR;
+
+       SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "function_js_rp"),    SCF_DFA_HOOK_PRE);
+       SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "function_js_comma"), SCF_DFA_HOOK_PRE);
+
+       d->argc = 0;
+       d->nb_lps++;
+
+       return SCF_DFA_NEXT_WORD;
+}
+
+static int _function_js_action_rp(scf_dfa_t* dfa, scf_vector_t* words, void* data)
+{
+       scf_parse_t*     parse = dfa->priv;
+       dfa_data_t*      d     = data;
+       dfa_fun_data_t*  fd    = d->module_datas[dfa_module_function_js.index];
+       scf_function_t*  f     = d->current_function;
+       scf_function_t*  fprev = NULL;
+       scf_lex_word_t*  w;
+
+       d->nb_rps++;
+
+       if (d->nb_rps < d->nb_lps) {
+               SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "function_js_rp"), SCF_DFA_HOOK_PRE);
+               return SCF_DFA_NEXT_WORD;
+       }
+
+       if (words->size < 2)
+               return SCF_DFA_ERROR;
+       w = words->data[words->size - 2];
+
+       if (scf_lex_is_identity(w)) {
+               if (_function_js_add_arg(parse->ast, w, d) < 0) {
+                       scf_loge("function_js add arg failed\n");
+                       return SCF_DFA_ERROR;
+               }
+       }
+
+       scf_list_del(&f->list);
+       scf_node_del_child((scf_node_t*)fd->parent_block, (scf_node_t*)f);
+
+       scf_block_t* b = fd->parent_block;
+
+       if (!b->node.root_flag && !b->node.file_flag) {
+               scf_loge("function_js should be defined in file, global\n");
+               return SCF_DFA_ERROR;
+       }
+
+       assert(b->scope);
+
+       if (SCF_LEX_WORD_KEY_FUNC != f->node.w->type) {
+               if (f->static_flag)
+                       fprev = scf_scope_find_function(b->scope, f->node.w->text->data);
+               else {
+                       int ret = scf_ast_find_global_function(&fprev, parse->ast, f->node.w->text->data);
+                       if (ret < 0)
+                               return ret;
+               }
+
+               if (fprev) {
+                       scf_loge("repeated declare function '%s', first in line: %d_%d, second in line: %d_%d\n",
+                                       f->node.w->text->data, fprev->node.w->line, fprev->node.w->pos, f->node.w->line, f->node.w->pos);
+                       return SCF_DFA_ERROR;
+               }
+       }
+
+       scf_scope_push_function(fd->parent_block->scope, f);
+
+       scf_node_add_child((scf_node_t*)fd->parent_block, (scf_node_t*)f);
+
+       SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "function_js_end"), SCF_DFA_HOOK_END);
+
+       parse->ast->current_block = (scf_block_t*)d->current_function;
+
+       return SCF_DFA_NEXT_WORD;
+}
+
+static int _function_js_action_end(scf_dfa_t* dfa, scf_vector_t* words, void* data)
+{
+       scf_parse_t*     parse = dfa->priv;
+       dfa_data_t*      d     = data;
+       scf_lex_word_t*  w     = words->data[words->size - 1];
+       dfa_fun_data_t*  fd    = d->module_datas[dfa_module_function_js.index];
+
+       parse->ast->current_block = (scf_block_t*)(fd->parent_block);
+
+       if (d->current_function->node.nb_nodes > 0)
+               d->current_function->node.define_flag = 1;
+
+       fd->parent_block = NULL;
+
+       d->current_function = NULL;
+       d->argc   = 0;
+       d->nb_lps = 0;
+       d->nb_rps = 0;
+
+       return SCF_DFA_OK;
+}
+
+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, 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);
+
+       scf_parse_t*     parse = dfa->priv;
+       dfa_data_t*      d     = parse->dfa_data;
+       dfa_fun_data_t*  fd    = d->module_datas[dfa_module_function_js.index];
+
+       assert(!fd);
+
+       fd = calloc(1, sizeof(dfa_fun_data_t));
+       if (!fd) {
+               scf_loge("\n");
+               return SCF_DFA_ERROR;
+       }
+
+       d->module_datas[dfa_module_function_js.index] = fd;
+
+       return SCF_DFA_OK;
+}
+
+static int _dfa_fini_module_function_js(scf_dfa_t* dfa)
+{
+       scf_parse_t*     parse = dfa->priv;
+       dfa_data_t*      d     = parse->dfa_data;
+       dfa_fun_data_t*  fd    = d->module_datas[dfa_module_function_js.index];
+
+       if (fd) {
+               free(fd);
+               fd = NULL;
+               d->module_datas[dfa_module_function_js.index] = NULL;
+       }
+
+       return SCF_DFA_OK;
+}
+
+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);
+       SCF_DFA_GET_MODULE_NODE(dfa, function_js, func,      func);
+       SCF_DFA_GET_MODULE_NODE(dfa, function_js, fname,     fname);
+       SCF_DFA_GET_MODULE_NODE(dfa, function_js, arg,       arg);
+
+       SCF_DFA_GET_MODULE_NODE(dfa, block,       entry,     block);
+
+       // function_js start
+       scf_vector_add(dfa->syntaxes, func);
+
+       scf_dfa_node_add_child(func,      fname);
+       scf_dfa_node_add_child(fname,     lp);
+       scf_dfa_node_add_child(func,      lp);
+
+       // function_js args
+       scf_dfa_node_add_child(lp,        rp);
+
+       scf_dfa_node_add_child(lp,        arg);
+       scf_dfa_node_add_child(arg,       comma);
+       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);
+
+       return 0;
+}
+
+scf_dfa_module_t dfa_module_function_js =
+{
+       .name        = "function_js",
+
+       .init_module = _dfa_init_module_function_js,
+       .init_syntax = _dfa_init_syntax_function_js,
+
+       .fini_module = _dfa_fini_module_function_js,
+};
index c13cda01229ed03ff308b3a88f43df40754cfd71..b3b647f4920752de29b1bc36fe0190bf9a8ef54a 100644 (file)
@@ -6,6 +6,7 @@ extern scf_dfa_module_t  dfa_module_init_data;
 
 int scf_array_init (scf_ast_t* ast, scf_lex_word_t* w, scf_variable_t* var, scf_vector_t* init_exprs);
 int scf_struct_init(scf_ast_t* ast, scf_lex_word_t* w, scf_variable_t* var, scf_vector_t* init_exprs);
+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);
 
@@ -32,42 +33,17 @@ static inline int _data_is_entry(scf_dfa_t* dfa, void* word)
        return SCF_LEX_WORD_LB == w->type || SCF_LEX_WORD_LS == w->type;
 }
 
-static int _do_data_init(scf_dfa_t* dfa, scf_vector_t* words, dfa_data_t* d)
+static int _do_data_init(scf_ast_t* ast, dfa_data_t* d, scf_variable_t* obj)
 {
-       scf_parse_t*        parse = dfa->priv;
-       scf_variable_t*     var   = d->current_var;
-       scf_lex_word_t*     w     = words->data[words->size - 1];
-       init_module_data_t* md    = d->module_datas[dfa_module_init_data.index];
+       init_module_data_t* md = d->module_datas[dfa_module_init_data.index];
        dfa_init_expr_t*    ie;
+       int i;
 
-       int ret = -1;
-       int i   = 0;
-
-       if (d->current_var->nb_dimentions > 0)
-               ret = scf_array_init(parse->ast, md->assign, d->current_var, md->init_exprs);
-
-       else if (d->current_var->type >=  SCF_STRUCT)
-               ret = scf_struct_init(parse->ast, md->assign, d->current_var, md->init_exprs);
-
-       if (ret < 0)
-               goto error;
+       int ret = scf_object_init(ast, md->assign, d->current_var, obj, md->init_exprs);
 
        for (i = 0; i < md->init_exprs->size; i++) {
                ie =        md->init_exprs->data[i];
 
-               ret = scf_node_add_child((scf_node_t*)parse->ast->current_block, ie->expr);
-               if (ret < 0)
-                       goto error;
-               ie->expr = NULL;
-
-               free(ie);
-               ie = NULL;
-       }
-
-error:
-       for (; i < md->init_exprs->size; i++) {
-               ie =   md->init_exprs->data[i];
-
                scf_expr_free(ie->expr);
                free(ie);
                ie = NULL;
@@ -76,7 +52,9 @@ error:
        md->assign = NULL;
 
        scf_vector_free(md->init_exprs);
+       scf_vector_free(md->init_objs);
        md->init_exprs = NULL;
+       md->init_objs  = NULL;
 
        free(md->current_index);
        md->current_index = NULL;
@@ -85,6 +63,7 @@ error:
        md->nb_lbs      = 0;
        md->nb_rbs      = 0;
 
+       d->current_var = NULL;
        return ret;
 }
 
@@ -111,11 +90,14 @@ static int _add_struct_member(scf_ast_t* ast, dfa_data_t* d, scf_variable_t* r)
                scf_scope_push_type(ast->current_block->scope, s);
                scf_node_add_child((scf_node_t*)ast->current_block, (scf_node_t*)s);
 
-               obj->type = s->type;
+               obj->type    = s->type;
+               obj->js_type = s->type;
+               scf_logi("obj->w: %s\n", obj->w->text->data);
        } else {
                int ret = scf_ast_find_type_type(&s, ast, obj->type);
                if (ret < 0)
                        return ret;
+               scf_logi("obj->w: %s\n", obj->w->text->data);
        }
 
        w = md->current_index[md->current_dim].w;
@@ -141,6 +123,7 @@ static int _add_struct_member(scf_ast_t* ast, dfa_data_t* d, scf_variable_t* r)
                scf_variable_free(r);
                return -ENOMEM;
        }
+       v->member_flag = 1;
 
        if (r->nb_dimentions > 0) {
                v->nb_dimentions = r->nb_dimentions;
@@ -161,6 +144,9 @@ static int _add_struct_member(scf_ast_t* ast, dfa_data_t* d, scf_variable_t* r)
        scf_variable_free(r);
        r = NULL;
 
+       if (v->type >= SCF_STRUCT)
+               v->js_type = v->type;
+
        scf_scope_push_var(s->scope, v);
        return 0;
 }
@@ -335,21 +321,16 @@ static int __data_add_obj(scf_dfa_t* dfa, scf_vector_t* words, void* data)
        d->expr = NULL;
        md->current_dim++;
 
-       if (md->current_dim >= md->current_n) {
-
-               void* p = realloc(md->current_index, sizeof(dfa_index_t) * (md->current_dim + 1));
-               if (!p)
-                       return -ENOMEM;
-               md->current_index = p;
-               md->current_n     = md->current_dim + 1;
-       }
+       scf_logd("w: %s, md->current_dim: %d\n", w->text->data, md->current_dim);
 
-       int i;
-       for (i = md->current_dim; i < md->current_n; i++) {
+       void* p = realloc(md->current_index, sizeof(dfa_index_t) * (md->current_dim + 1));
+       if (!p)
+               return -ENOMEM;
+       md->current_index = p;
+       md->current_n     = md->current_dim + 1;
 
-               md->current_index[i].w = NULL;
-               md->current_index[i].i = 0;
-       }
+       md->current_index[md->current_dim].w = NULL;
+       md->current_index[md->current_dim].i = 0;
 
        return 0;
 }
@@ -441,12 +422,14 @@ static int _data_action_rb(scf_dfa_t* dfa, scf_vector_t* words, void* data)
        md->nb_rbs++;
        md->current_dim--;
 
+       scf_logd("md->current_dim: %d, md->current_n: %d\n", md->current_dim, md->current_n);
+
        int i;
        for (i = md->current_dim + 1; i < md->current_n; i++) {
-
                md->current_index[i].w = NULL;
                md->current_index[i].i = 0;
        }
+       md->current_n--;
 
        obj = scf_stack_pop(md->init_objs);
 
@@ -460,8 +443,8 @@ static int _data_action_rb(scf_dfa_t* dfa, scf_vector_t* words, void* data)
        if (md->nb_rbs == md->nb_lbs) {
                d->expr_local_flag = 0;
 
-               scf_logi("-----------\n\n");
-
+               scf_logi("----------- type: %d, nb_pointers: %d\n\n", d->current_var->type, d->current_var->nb_pointers);
+#if 0
                d->current_var->type        = obj->type;
                d->current_var->size        = obj->size;
                d->current_var->data_size   = obj->data_size;
@@ -469,7 +452,13 @@ static int _data_action_rb(scf_dfa_t* dfa, scf_vector_t* words, void* data)
 
                if (_do_data_init(dfa, words, d) < 0)
                        return SCF_DFA_ERROR;
+#else
+               d->current_var->js_type = obj->type;
 
+               ret = _do_data_init(parse->ast, d, obj);
+               if (ret < 0)
+                       return ret;
+#endif
                scf_dfa_del_hook_by_name(&(dfa->hooks[SCF_DFA_HOOK_POST]), "init_data_comma");
        } else {
                w = md->current_index[md->current_dim].w;
@@ -527,23 +516,20 @@ static int _data_action_rs(scf_dfa_t* dfa, scf_vector_t* words, void* data)
                md->current_index[i].i = 0;
        }
 
+       md->current_n--;
+
        scf_stack_pop(md->init_objs);
 
        if (md->init_objs->size <= 0) {
                d->expr_local_flag = 0;
 
-               d->current_var->type          = obj->type;
-               d->current_var->size          = obj->size;
-               d->current_var->data_size     = obj->data_size;
-               d->current_var->nb_pointers   = obj->nb_pointers;
-
-               assert(d->current_var->nb_dimentions == obj->nb_dimentions);
+               scf_logi("----------- type: %d, nb_pointers: %d\n\n", d->current_var->type, d->current_var->nb_pointers);
 
-               for (i = 0; i < obj->nb_dimentions; i++)
-                       d->current_var->dimentions[i].num = obj->dimentions[i].num;
+               d->current_var->js_type = obj->type;
 
-               if (_do_data_init(dfa, words, d) < 0)
-                       return SCF_DFA_ERROR;
+               ret = _do_data_init(parse->ast, d, obj);
+               if (ret < 0)
+                       return ret;
 
                scf_dfa_del_hook_by_name(&(dfa->hooks[SCF_DFA_HOOK_POST]), "init_data_rs");
                scf_dfa_del_hook_by_name(&(dfa->hooks[SCF_DFA_HOOK_POST]), "init_data_comma");
index 495c411fb6840cc4f44f06683da43a731d47c6dc..2654ceeea89ca605b7b5bce06ba522f6d50e1677 100644 (file)
@@ -23,6 +23,7 @@ extern scf_dfa_module_t  dfa_module_type;
 extern scf_dfa_module_t  dfa_module_var;
 
 extern scf_dfa_module_t  dfa_module_function;
+extern scf_dfa_module_t  dfa_module_function_js;
 extern scf_dfa_module_t  dfa_module_operator;
 
 extern scf_dfa_module_t  dfa_module_if;
@@ -59,6 +60,7 @@ scf_dfa_module_t* dfa_modules[] =
        &dfa_module_enum,
        &dfa_module_union,
        &dfa_module_class,
+       &dfa_module_function_js,
 
        &dfa_module_type,
 
index 46801e739ce6d29ec370a4b3c705e9b91f6111a7..84e07337cf4d791032c1e43a8c78c4fce2d5ec7d 100644 (file)
@@ -326,4 +326,11 @@ static inline int scf_dfa_is_var(scf_dfa_t* dfa, void* word)
        return SCF_LEX_WORD_KEY_VAR == w->type;
 }
 
+static inline int scf_dfa_is_func(scf_dfa_t* dfa, void* word)
+{
+       scf_lex_word_t* w = word;
+
+       return SCF_LEX_WORD_KEY_FUNC == w->type;
+}
+
 #endif
index 91b88fa331b6cb1cc98c4360961e07178bac5ae5..45b7608ebbfdc16c8735214964e5fa6a4c5a79c7 100644 (file)
@@ -120,6 +120,13 @@ static int _var_add_var(scf_dfa_t* dfa, dfa_data_t* d)
                        return SCF_DFA_ERROR;
                }
 
+               if (SCF_VAR_VAR == id0->type->type) {
+                       id0->nb_pointers = 1;
+
+                       if (scf_ast_find_type(&id0->type, parse->ast, "Object") < 0)
+                               return SCF_DFA_ERROR;
+               }
+
                v = SCF_VAR_ALLOC_BY_TYPE(id->identity, id0->type, id0->const_flag, id0->nb_pointers, id0->func_ptr);
                if (!v) {
                        scf_loge("alloc var failed\n");
@@ -158,7 +165,6 @@ static int _var_add_var(scf_dfa_t* dfa, dfa_data_t* d)
 static int _var_init_expr(scf_dfa_t* dfa, dfa_data_t* d, scf_vector_t* words, int semi_flag)
 {
        scf_parse_t*    parse = dfa->priv;
-       scf_variable_t* r     = NULL;
        scf_lex_word_t* w     = words->data[words->size - 1];
        scf_node_t*     node0;
        scf_node_t*     node1;
@@ -171,21 +177,6 @@ static int _var_init_expr(scf_dfa_t* dfa, dfa_data_t* d, scf_vector_t* words, in
 
        assert(d->current_var);
 
-       if (SCF_VAR_VAR == d->current_var->type) {
-               if (scf_expr_calculate(parse->ast, d->expr, &r) < 0) {
-                       scf_loge("\n");
-                       goto error;
-               }
-
-               d->current_var->type        = r->type;
-               d->current_var->size        = r->size;
-               d->current_var->data_size   = r->data_size;
-               d->current_var->nb_pointers = r->nb_pointers;
-       }
-
-       scf_variable_free(r);
-       r = NULL;
-
        node0 = scf_node_alloc(w, SCF_OP_ASSIGN, NULL);
        if (!node0)
                goto error;
index 6a6d0af3a462e76b201fe6d7fc1721ff063c2430..01f76ecbbd7a024a191193ae353def874d83f21e 100644 (file)
@@ -1902,7 +1902,7 @@ int scf_parse_compile_functions(scf_parse_t* parse, scf_vector_t* functions)
                }
 
                assert(scf_list_empty(&h));
-               scf_basic_block_print_list(&f->basic_block_list_head);
+//             scf_basic_block_print_list(&f->basic_block_list_head);
        }
 
        int ret = scf_optimize(parse->ast, functions);
index 5b45bb4030bdc4caf719e99936e3a851634e318a..aa89b4c976c83c02aeca8bb73461d592dd7c89b1 100644 (file)
@@ -132,4 +132,15 @@ int scf_parse_link(const char* exec, const char* obj, const char* libjs, const c
 int _find_global_var(scf_node_t* node, void* arg, scf_vector_t* vec);
 int _find_function  (scf_node_t* node, void* arg, scf_vector_t* vec);
 
+static inline int dfa_index_same(dfa_index_t* di, dfa_index_t* di2)
+{
+       if (di->w) {
+               if (di2->w && !strcmp(di->w->text->data, di2->w->text->data))
+                       return 1;
+       } else {
+               if (!di2->w && di->i >= 0 && di->i == di2->i)
+                       return 1;
+       }
+       return 0;
+}
 #endif
index 8e8c72052f5cbeb54522b55ce88e7f43712af6c6..4c16cdfecbbceffb3591aeb262f2ec6ec0ea0a9b 100644 (file)
@@ -369,3 +369,330 @@ int scf_struct_init(scf_ast_t* ast, scf_lex_word_t* w, scf_variable_t* var, scf_
 
        return 0;
 }
+
+static int __object_create(scf_expr_t* e, scf_ast_t* ast, scf_lex_word_t* w, scf_variable_t* var, int n_members, scf_type_t* Object,
+               scf_vector_t* init_exprs,
+               scf_vector_t* init_pos)
+{
+       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;
+
+       assign = scf_node_alloc(w, SCF_OP_ASSIGN, NULL);
+       if (!assign)
+               return -ENOMEM;
+
+       int ret = scf_expr_add_node(e, assign);
+       if (ret < 0) {
+               scf_node_free(assign);
+               return ret;
+       }
+
+       b = scf_block_alloc_cstr("multi_rets");
+       if (!b)
+               return -ENOMEM;
+
+       ret = scf_node_add_child((scf_node_t*)b, assign->nodes[0]);
+       if (ret < 0)
+               return ret;
+       assign->nodes[0] = (scf_node_t*)b;
+       b->node.parent   = assign;
+
+       create = scf_node_alloc(w, SCF_OP_CREATE, NULL);
+       if (!create)
+               return -ENOMEM;
+
+       // add construct() for obj
+       v = SCF_VAR_ALLOC_BY_TYPE(Object->w, pt, 1, 1, NULL);
+       if (!v) {
+               scf_node_free(create);
+               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(create);
+               return -ENOMEM;
+       }
+
+       ret = scf_node_add_child(create, node);
+       if (ret < 0) {
+               scf_node_free(node);
+               scf_node_free(create);
+               return ret;
+       }
+
+       // add obj name
+       ret = scf_ast_add_const_str(ast, create, var->w);
+       if (ret < 0) {
+               scf_node_free(create);
+               return ret;
+       }
+
+       // add obj members
+       ret = scf_ast_add_const_var(ast, create, SCF_VAR_INT, n_members);
+       if (ret < 0) {
+               scf_node_free(create);
+               return ret;
+       }
+
+       if (0 == n_members && init_exprs && init_pos) {
+               dfa_init_expr_t* ie;
+               dfa_index_t*     di;
+               int i;
+               int j;
+
+               for (i = 0; i < init_exprs->size; i++) {
+                       ie =        init_exprs->data[i];
+
+                       if (ie->n != init_pos->size) {
+                               scf_logw("var: %s, ie->n: %d, init_pos->size: %d\n", var->w->text->data, ie->n, init_pos->size);
+                               continue;
+                       }
+
+                       for (j = 0; j < init_pos->size; j++) {
+                               di        = init_pos->data[j];
+
+                               if (!dfa_index_same(&ie->index[j], di)) {
+                                       scf_logw("var: %s\n", var->w->text->data);
+                                       break;
+                               }
+                       }
+
+                       if (j >= init_pos->size) {
+                               assert(ie->expr);
+
+                               scf_logi("var: %s\n", var->w->text->data);
+
+                               ret = scf_node_add_child(create, ie->expr);
+                               if (ret < 0) {
+                                       scf_node_free(create);
+                                       return ret;
+                               }
+
+                               ie->expr = NULL;
+                               assert(0 == scf_vector_del(init_exprs, ie));
+                               free(ie);
+                               ie = NULL;
+                               break;
+                       }
+               }
+       }
+
+       ret = scf_expr_add_node(e, create);
+       if (ret < 0) {
+               scf_node_free(create);
+               return ret;
+       }
+       return 0;
+}
+
+#define OBJ_EXPR_ADD_NODE(_e, _node) \
+       do { \
+               int ret = scf_expr_add_node(_e, _node); \
+               if (ret < 0) { \
+                       scf_node_free(_node); \
+                       scf_expr_free(_e); \
+                       return ret; \
+               } \
+       } while (0)
+
+static int __object_init(scf_ast_t* ast, scf_expr_t* e, scf_lex_word_t* w, scf_variable_t* var, scf_variable_t* obj, scf_type_t* Object,
+               scf_variable_t* members,
+               int             array_dim,
+               scf_vector_t*   init_exprs,
+               scf_vector_t*   init_pos)
+{
+       scf_type_t*  t = NULL;
+       scf_expr_t*  e2;
+       scf_expr_t*  e3;
+       scf_node_t*  node;
+
+       int ret = scf_ast_find_type_type(&t, ast, obj->type);
+       if (ret < 0)
+               return ret;
+
+       e2 = scf_expr_clone(e);
+       if (!e2) {
+               scf_expr_free(e);
+               return -ENOMEM;
+       }
+
+       if (array_dim < obj->nb_dimentions) {
+               scf_logi("var: %s, array_dim: %d, nb_dimentions: %d, num: %d\n",
+                               var->w->text->data, array_dim, obj->nb_dimentions,
+                               obj->dimentions[array_dim].num);
+
+               ret = __object_create(e, ast, w, var, obj->dimentions[array_dim].num, Object, NULL, NULL);
+
+       } else if (t->type >= SCF_STRUCT) {
+               scf_logd("var: %s\n", var->w->text->data);
+               ret = __object_create(e, ast, w, var, t->scope->vars->size, Object, NULL, NULL);
+       } else {
+               scf_logd("var: %s\n", var->w->text->data);
+               ret = __object_create(e, ast, w, var, 0, Object, init_exprs, init_pos);
+       }
+       if (ret < 0) {
+               scf_expr_free(e);
+               scf_expr_free(e2);
+               return ret;
+       }
+
+       ret = scf_node_add_child((scf_node_t*)ast->current_block, e);
+       if (ret < 0) {
+               scf_expr_free(e);
+               scf_expr_free(e2);
+               return ret;
+       }
+       e = NULL;
+
+       if (t->type >= SCF_STRUCT || array_dim < obj->nb_dimentions) {
+               // add ->
+               node = scf_node_alloc(w, SCF_OP_POINTER, NULL);
+               if (!node) {
+                       scf_expr_free(e2);
+                       return -ENOMEM;
+               }
+               OBJ_EXPR_ADD_NODE(e2, node);
+
+               // add members
+               node = scf_node_alloc(NULL, members->type, members);
+               if (!node) {
+                       scf_expr_free(e2);
+                       return -ENOMEM;
+               }
+               OBJ_EXPR_ADD_NODE(e2, node);
+
+               int i;
+               int n;
+               if (array_dim < obj->nb_dimentions)
+                       n = obj->dimentions[array_dim].num;
+               else
+                       n = t->scope->vars->size;
+
+               for (i = 0; i < n; i++) {
+                       e3 = scf_expr_clone(e2);
+                       if (!e3) {
+                               scf_expr_free(e2);
+                               return -ENOMEM;
+                       }
+
+                       node = scf_node_alloc(w, SCF_OP_ARRAY_INDEX, NULL);
+                       if (!node) {
+                               scf_expr_free(e3);
+                               scf_expr_free(e2);
+                               return -ENOMEM;
+                       }
+
+                       ret = scf_expr_add_node(e3, node);
+                       if (ret < 0) {
+                               scf_node_free(node);
+                               scf_expr_free(e3);
+                               scf_expr_free(e2);
+                               return ret;
+                       }
+
+                       scf_variable_t* v = NULL;
+
+                       if (array_dim < obj->nb_dimentions)
+                               ret = scf_ast_add_const_var(ast, node, SCF_VAR_INT, i);
+                       else {
+                               v = t->scope->vars->data[i];
+                               ret = scf_ast_add_const_var(ast, node, SCF_VAR_INT, v->js_index);
+                       }
+                       if (ret < 0) {
+                               scf_expr_free(e3);
+                               scf_expr_free(e2);
+                               return ret;
+                       }
+
+                       dfa_index_t* di = calloc(1, sizeof(dfa_index_t));
+                       if (!di) {
+                               scf_expr_free(e3);
+                               scf_expr_free(e2);
+                               return -ENOMEM;
+                       }
+
+                       ret = scf_vector_add(init_pos, di);
+                       if (ret < 0) {
+                               free(di);
+                               scf_expr_free(e3);
+                               scf_expr_free(e2);
+                               return ret;
+                       }
+
+                       if (v) {
+                               di->w = v->w;
+                               di->i = -1;
+                               scf_logi("i: %d, n: %d\n", i, n);
+
+                               ret = __object_init(ast, e3, w, v, v, Object, members, array_dim, init_exprs, init_pos);
+                       } else {
+                               di->w = NULL;
+                               di->i = i;
+                               scf_logi("i: %d, n: %d\n", i, n);
+
+                               ret = __object_init(ast, e3, w, var, obj, Object, members, array_dim + 1, init_exprs, init_pos);
+                       }
+                       if (ret < 0) {
+                               scf_expr_free(e2);
+                               return ret;
+                       }
+
+                       assert(0 == scf_vector_del(init_pos, di));
+                       free(di);
+                       di = NULL;
+
+                       scf_logi("init_pos->size: %d\n", init_pos->size);
+               }
+       }
+
+       scf_expr_free(e2);
+       e2 = NULL;
+       return 0;
+}
+
+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)
+{
+       scf_vector_t*    init_pos;
+       scf_variable_t*  members = NULL;
+       scf_type_t*      Object  = NULL;
+       scf_node_t*      node;
+       scf_expr_t*      e;
+
+       int ret = scf_ast_find_type(&Object, ast, "Object");
+       if (ret < 0)
+               return ret;
+
+       members = scf_scope_find_variable(Object->scope, "members");
+       if (!members)
+               return -1;
+
+       e = scf_expr_alloc();
+       if (!e)
+               return -ENOMEM;
+
+       node = scf_node_alloc(NULL, var->type, var);
+       if (!node) {
+               scf_expr_free(e);
+               return -ENOMEM;
+       }
+       OBJ_EXPR_ADD_NODE(e, node);
+
+       init_pos = scf_vector_alloc();
+       if (!init_pos) {
+               scf_expr_free(e);
+               return -ENOMEM;
+       }
+
+       ret = __object_init(ast, e, w, var, obj, Object, members, 0, init_exprs, init_pos);
+
+       scf_vector_free(init_pos);
+       return ret;
+}
index acc583572b40aa326d05cef3d2c8b1a1620c5f51..fade2746baf5d336b14d3f8db560bfe03a42bdc7 100644 (file)
@@ -198,6 +198,7 @@ CFILES += ../js/parse/scf_dfa_type.c
 CFILES += ../js/parse/scf_dfa_identity.c
 
 CFILES += ../js/parse/scf_dfa_function.c
+CFILES += ../js/parse/scf_dfa_function_js.c
 CFILES += ../js/parse/scf_dfa_operator.c
 CFILES += ../js/parse/scf_dfa_var.c