typedef struct {
scf_block_t* parent_block;
+ scf_function_t* f;
scf_variable_t* v_pf;
- int pf_lps;
- int pf_rps;
+ int argc;
+ int nb_lps;
+ int nb_rps;
+
} dfa_fun_data_t;
int _function_add_function(scf_dfa_t* dfa, dfa_data_t* d)
scf_parse_t* parse = dfa->priv;
scf_ast_t* ast = parse->ast;
dfa_identity_t* id = NULL;
- dfa_fun_data_t* fd = d->module_datas[dfa_module_function.index];
+ scf_stack_t* s = d->module_datas[dfa_module_function.index];
+ dfa_fun_data_t* fd = scf_stack_top(s);
scf_lex_word_t* name = NULL;
dfa_identity_t* id0;
id = NULL;
}
- scf_logi("function: %s(), line: %d, member_flag: %d\n", f->node.w->text->data, f->node.w->line, f->member_flag);
+ scf_logi("s->size: %d, function: %s(), line: %d, member_flag: %d\n", s->size, f->node.w->text->data, f->node.w->line, f->member_flag);
int void_flag = 0;
SCF_XCHG(f->rets->data[i], f->rets->data[j]);
}
- if (!f->member_flag || v_pf) {
-
- b = ast->current_block;
- while (b) {
- if (b->node.file_flag)
- break;
- b = (scf_block_t*)b->node.parent;
- }
+ if (v_pf) {
+ v_pf->static_flag = f->static_flag;
+ v_pf->func_ptr = f;
+ }
- scf_scope_push_function(b->scope, f);
+ scf_scope_push_function(ast->current_block->scope, f);
- scf_node_add_child((scf_node_t*)b, (scf_node_t*)f);
-
- if (v_pf) {
- v_pf->static_flag = f->static_flag;
- v_pf->func_ptr = f;
- }
- } else {
- scf_scope_push_function(ast->current_block->scope, f);
-
- scf_node_add_child((scf_node_t*)ast->current_block, (scf_node_t*)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;
+ fd->f = f;
return SCF_DFA_NEXT_WORD;
}
int _function_add_arg(scf_dfa_t* dfa, dfa_data_t* d)
{
- dfa_identity_t* t = NULL;
- dfa_identity_t* v = NULL;
+ scf_stack_t* s = d->module_datas[dfa_module_function.index];
+ dfa_fun_data_t* fd = scf_stack_top(s);
+ dfa_identity_t* t = NULL;
+ dfa_identity_t* v = NULL;
switch (d->current_identities->size) {
case 0:
break;
+
case 1:
t = scf_stack_pop(d->current_identities);
- assert(t && t->type);
+ assert(t);
+
+ if (!t->type) {
+ scf_loge("NO type found for '%s', file: %s, line: %d\n",
+ t->identity->text->data,
+ t->identity->file->data, t->identity->line);
+
+ free(t);
+ return SCF_DFA_ERROR;
+ }
break;
+
case 2:
v = scf_stack_pop(d->current_identities);
t = scf_stack_pop(d->current_identities);
- assert(t && t->type);
+ assert(t);
assert(v && v->identity);
+
+ if (!t->type) {
+ scf_loge("NO type found for '%s', file: %s, line: %d\n",
+ t->identity->text->data,
+ t->identity->file->data, t->identity->line);
+
+ free(t);
+ free(v);
+ return SCF_DFA_ERROR;
+ }
break;
default:
scf_loge("\n");
break;
};
- if (t && t->type) {
- scf_variable_t* arg = NULL;
- scf_lex_word_t* w = NULL;
+ scf_variable_t* arg = NULL;
+ scf_lex_word_t* w = NULL;
+ if (t && t->type) {
if (v && v->identity)
w = v->identity;
if (!arg)
return SCF_DFA_ERROR;
- scf_scope_push_var(d->current_function->scope, arg);
- } else {
+ scf_scope_push_var(fd->f->scope, arg);
+ } else
arg = d->current_var;
- if (arg->nb_dimentions > 0) {
- arg->nb_pointers += arg->nb_dimentions;
- arg->nb_dimentions = 0;
- }
+ if (v) {
+ free(v);
+ v = NULL;
+ }
- if (arg->dimentions) {
- free(arg->dimentions);
- arg->dimentions = NULL;
- }
+ free(t);
+ t = NULL;
- arg->const_literal_flag = 0;
+ } else {
+ if (!d->current_var)
+ return SCF_DFA_NEXT_WORD;
- d->current_var = NULL;
- }
+ arg = d->current_var;
+ }
- scf_logi("d->argc: %d, arg->nb_pointers: %d, arg->nb_dimentions: %d\n",
- d->argc, arg->nb_pointers, arg->nb_dimentions);
+ d->current_var = NULL;
- scf_vector_add(d->current_function->argv, arg);
+ if (arg->nb_dimentions > 0) {
+ arg->nb_pointers += arg->nb_dimentions;
+ arg->nb_dimentions = 0;
+ }
- arg->refs++;
- arg->arg_flag = 1;
- arg->local_flag = 1;
+ if (arg->dimentions) {
+ free(arg->dimentions);
+ arg->dimentions = NULL;
+ }
- if (v)
- free(v);
- free(t);
+ arg->const_literal_flag = 0;
- d->argc++;
- }
+ scf_logi("s->size: %d, fd->f: %s(), fd->argc: %d, arg->nb_pointers: %d, arg->nb_dimentions: %d\n",
+ s->size, fd->f->node.w->text->data, fd->argc, arg->nb_pointers, arg->nb_dimentions);
+
+ assert(scf_vector_find(fd->f->scope->vars, arg));
+
+ scf_vector_add(fd->f->argv, arg);
+
+ arg->refs++;
+ arg->arg_flag = 1;
+ arg->local_flag = 1;
+
+ fd->argc++;
return SCF_DFA_NEXT_WORD;
}
static int _function_action_vargs(scf_dfa_t* dfa, scf_vector_t* words, void* data)
{
- dfa_data_t* d = data;
+ dfa_data_t* d = data;
+ scf_stack_t* s = d->module_datas[dfa_module_function.index];
+ dfa_fun_data_t* fd = scf_stack_top(s);
- d->current_function->vargs_flag = 1;
+ fd->f->vargs_flag = 1;
return SCF_DFA_NEXT_WORD;
}
static int _function_action_pf_star(scf_dfa_t* dfa, scf_vector_t* words, void* data)
{
- dfa_data_t* d = data;
- dfa_fun_data_t* fd = d->module_datas[dfa_module_function.index];
+ dfa_data_t* d = data;
d->pf_pointers++;
static int _function_action_pf_lp(scf_dfa_t* dfa, scf_vector_t* words, void* data)
{
- dfa_data_t* d = data;
- dfa_fun_data_t* fd = d->module_datas[dfa_module_function.index];
+ dfa_data_t* d = data;
- fd->pf_lps++;
+ d->pf_lps++;
SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "function_pf_rp"), SCF_DFA_HOOK_PRE);
static int _function_action_pf_rp(scf_dfa_t* dfa, scf_vector_t* words, void* data)
{
- dfa_data_t* d = data;
- dfa_fun_data_t* fd = d->module_datas[dfa_module_function.index];
- dfa_identity_t* id = scf_stack_top(d->current_identities);
+ dfa_data_t* d = data;
+ dfa_identity_t* id = scf_stack_top(d->current_identities);
- fd->pf_rps++;
+ d->pf_rps++;
- if (fd->pf_rps == fd->pf_lps) {
- fd->pf_rps = 0;
- fd->pf_lps = 0;
+ if (d->pf_rps == d->pf_lps) {
+ d->pf_rps = 0;
+ d->pf_lps = 0;
if (id && id->identity)
scf_logw("pf: %s(), nb_pointers: %d\n", id->identity->text->data, d->pf_pointers);
{
scf_parse_t* parse = dfa->priv;
dfa_data_t* d = data;
- dfa_fun_data_t* fd = d->module_datas[dfa_module_function.index];
+ scf_stack_t* s = d->module_datas[dfa_module_function.index];
+ dfa_fun_data_t* fd = calloc(1, sizeof(dfa_fun_data_t));
+
+ if (!fd)
+ return -ENOMEM;
+
+ int ret = scf_stack_push(s, fd);
+ if (ret < 0)
+ return ret;
assert(!d->current_node);
if (d->pf_pointers <= 0)
d->current_var = NULL;
- if (_function_add_function(dfa, d) < 0)
- return SCF_DFA_ERROR;
+ ret = _function_add_function(dfa, d);
+ if (ret < 0)
+ return ret;
d->current_var = NULL;
SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "function_rp"), SCF_DFA_HOOK_PRE);
SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "function_comma"), SCF_DFA_HOOK_PRE);
- d->argc = 0;
- d->nb_lps++;
+ fd->nb_lps++;
return SCF_DFA_NEXT_WORD;
}
static int _function_action_rp(scf_dfa_t* dfa, scf_vector_t* words, void* data)
{
scf_parse_t* parse = dfa->priv;
+ scf_lex_word_t* w = words->data[words->size - 1];
dfa_data_t* d = data;
- dfa_fun_data_t* fd = d->module_datas[dfa_module_function.index];
- scf_function_t* f = d->current_function;
+ scf_stack_t* s = d->module_datas[dfa_module_function.index];
+
+ dfa_fun_data_t* fd = scf_stack_top(s);
+ scf_function_t* f = fd->f;
scf_function_t* fprev = NULL;
+ scf_block_t* b = fd->parent_block;
- d->nb_rps++;
+ if (fd->nb_rps < fd->nb_lps) {
+ fd->nb_rps++;
- if (d->nb_rps < d->nb_lps) {
- SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "function_rp"), SCF_DFA_HOOK_PRE);
- return SCF_DFA_NEXT_WORD;
- }
+ if (fd->nb_rps < fd->nb_lps) {
+ SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "function_rp"), SCF_DFA_HOOK_PRE);
+ return SCF_DFA_NEXT_WORD;
+ }
- if (_function_add_arg(dfa, d) < 0) {
- scf_loge("function add arg failed\n");
+ } else {
+ scf_loge("too many ')' for function: %s(), file: %s, line: %d\n", f->node.w->text->data, w->file->data, w->line);
return SCF_DFA_ERROR;
}
- scf_list_del(&f->list);
- scf_node_del_child((scf_node_t*)fd->parent_block, (scf_node_t*)f);
+ scf_logi("f: %s(), fd->nb_lps: %d, fd->nb_rps: %d\n", f->node.w->text->data, fd->nb_lps, fd->nb_rps);
- if (fd->parent_block->node.type >= SCF_STRUCT) {
+ if (_function_add_arg(dfa, d) < 0)
+ return SCF_DFA_ERROR;
- scf_type_t* t = (scf_type_t*)fd->parent_block;
+ scf_list_del(&f->list);
+ scf_node_del_child((scf_node_t*)b, (scf_node_t*)f);
- if (!t->node.class_flag) {
+ if (b->node.type >= SCF_STRUCT) {
+
+ if (!b->node.class_flag) {
scf_loge("only class has member function\n");
return SCF_DFA_ERROR;
}
- assert(t->scope);
+ assert(b->scope);
if (!strcmp(f->node.w->text->data, "__init")) {
- fprev = scf_scope_find_same_function(t->scope, f);
+ fprev = scf_scope_find_same_function(b->scope, f);
} else if (!strcmp(f->node.w->text->data, "__release")) {
- fprev = scf_scope_find_function(t->scope, f->node.w->text->data);
+ fprev = scf_scope_find_function(b->scope, f->node.w->text->data);
if (fprev && !scf_function_same(fprev, f)) {
scf_loge("function '%s' can't be overloaded, repeated declare first in line: %d, second in line: %d\n",
return SCF_DFA_ERROR;
}
} else {
- scf_block_t* b = fd->parent_block;
+ while (b) {
+ if (b->node.root_flag || b->node.file_flag)
+ break;
- if (!b->node.root_flag && !b->node.file_flag) {
- scf_loge("function should be defined in file, global, or class\n");
- return SCF_DFA_ERROR;
+ b = (scf_block_t*)b->node.parent;
}
- assert(b->scope);
+ assert(b && b->scope);
if (f->static_flag)
fprev = scf_scope_find_function(b->scope, f->node.w->text->data);
SCF_XCHG(v0->w, v1->w);
}
+ if (fd->v_pf) {
+ assert(fd->v_pf->func_ptr == fd->f);
+
+ fd->v_pf->func_ptr = fprev;
+ }
+
scf_function_free(f);
- d->current_function = fprev;
+ fd->f = fprev;
} else {
scf_lex_word_t* w = dfa->ops->pop_word(dfa);
dfa->ops->push_word(dfa, w);
}
} else {
- scf_scope_push_function(fd->parent_block->scope, f);
+ scf_scope_push_function(b->scope, f);
- scf_node_add_child((scf_node_t*)fd->parent_block, (scf_node_t*)f);
+ scf_node_add_child((scf_node_t*)b, (scf_node_t*)f);
}
- SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "function_end"), SCF_DFA_HOOK_END);
+ if (s->size <= 1)
+ SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "function_end"), SCF_DFA_HOOK_END);
+ else {
+ assert(!d->current_var);
- parse->ast->current_block = (scf_block_t*)d->current_function;
+ d->current_var = fd->v_pf;
+ fd->v_pf = NULL;
+
+ scf_logd("fd->f: %s(), d->current_var: %p\n", fd->f->node.w->text->data, d->current_var);
+
+ scf_stack_pop(s);
+ free(fd);
+
+ fd = scf_stack_top(s);
+ }
+
+ parse->ast->current_block = (scf_block_t*)fd->f;
return SCF_DFA_NEXT_WORD;
}
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.index];
+ scf_stack_t* s = d->module_datas[dfa_module_function.index];
+ dfa_fun_data_t* fd = scf_stack_pop(s);
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 (fd->f->node.nb_nodes > 0)
+ fd->f->node.define_flag = 1;
fd->parent_block = NULL;
- d->current_function = NULL;
- d->argc = 0;
- d->nb_lps = 0;
- d->nb_rps = 0;
+ fd->nb_lps = 0;
+ fd->nb_rps = 0;
+ scf_logi("s->size: %d\n", s->size);
+
+ free(fd);
return SCF_DFA_OK;
}
SCF_DFA_MODULE_NODE(dfa, function, pf_lp, scf_dfa_is_lp, _function_action_pf_lp);
SCF_DFA_MODULE_NODE(dfa, function, pf_rp, scf_dfa_is_rp, _function_action_pf_rp);
- scf_parse_t* parse = dfa->priv;
- dfa_data_t* d = parse->dfa_data;
- dfa_fun_data_t* fd = d->module_datas[dfa_module_function.index];
+ scf_parse_t* parse = dfa->priv;
+ dfa_data_t* d = parse->dfa_data;
+ scf_stack_t* s = d->module_datas[dfa_module_function.index];
- assert(!fd);
+ assert(!s);
- fd = calloc(1, sizeof(dfa_fun_data_t));
- if (!fd) {
- scf_loge("\n");
+ s = scf_stack_alloc();
+ if (!s)
return SCF_DFA_ERROR;
- }
- d->module_datas[dfa_module_function.index] = fd;
+ d->module_datas[dfa_module_function.index] = s;
return SCF_DFA_OK;
}
static int _dfa_fini_module_function(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.index];
+ scf_parse_t* parse = dfa->priv;
+ dfa_data_t* d = parse->dfa_data;
+ scf_stack_t* s = d->module_datas[dfa_module_function.index];
- if (fd) {
- free(fd);
- fd = NULL;
+ if (s) {
+ scf_stack_free(s);
d->module_datas[dfa_module_function.index] = NULL;
}