From: yu.dongliang <18588496441@163.com> Date: Fri, 22 Aug 2025 09:11:39 +0000 (+0800) Subject: js: anonymous function & var init ok X-Git-Url: http://baseworks.info/?a=commitdiff_plain;h=47630a5f0ddcaa297936e14cffccda102aab88ec;p=abc.git js: anonymous function & var init ok --- diff --git a/examples/js.html b/examples/js.html index 8716472..5811a56 100644 --- a/examples/js.html +++ b/examples/js.html @@ -7,14 +7,12 @@

含有js的页面

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