From: yu.dongliang <18588496441@163.com> Date: Thu, 8 Jun 2023 06:12:47 +0000 (+0800) Subject: support 'do {} while ()' X-Git-Url: http://baseworks.info/?a=commitdiff_plain;h=e5730ae55dd83158aad07a80eca7ebc0dabc3294;p=scf.git support 'do {} while ()' --- diff --git a/core/scf_core_types.h b/core/scf_core_types.h index 769e90d..6c48bfc 100644 --- a/core/scf_core_types.h +++ b/core/scf_core_types.h @@ -99,6 +99,7 @@ enum scf_core_types { SCF_OP_IF, // if statement SCF_OP_FOR, // for statement SCF_OP_WHILE, // while statement + SCF_OP_REPEAT, // repeat statement SCF_OP_RETURN, // return statement SCF_OP_BREAK, // break statement SCF_OP_CONTINUE, // continue statement diff --git a/core/scf_expr.c b/core/scf_expr.c index 81829c6..c3c94ac 100644 --- a/core/scf_expr.c +++ b/core/scf_expr.c @@ -21,6 +21,43 @@ scf_expr_t* scf_expr_alloc() return e; } +int scf_expr_copy(scf_node_t* e2, scf_node_t* e) +{ + scf_node_t* node; + + int i; + for (i = 0; i < e->nb_nodes; i++) { + + node = scf_node_clone(e->nodes[i]); + + if (!node) + return -ENOMEM; + + scf_node_add_child(e2, node); + + int ret = scf_expr_copy(e2->nodes[i], e->nodes[i]); + if (ret < 0) + return ret; + } + + return 0; +} + +scf_expr_t* scf_expr_clone(scf_node_t* e) +{ + scf_expr_t* e2 = scf_expr_alloc(); + + if (!e2) + return NULL; + + if (scf_expr_copy(e2, e) < 0) { + scf_expr_free(e2); + return NULL; + } + + return e2; +} + void scf_expr_free(scf_expr_t* e) { if (e) { diff --git a/core/scf_expr.h b/core/scf_expr.h index 3856902..7029b68 100644 --- a/core/scf_expr.h +++ b/core/scf_expr.h @@ -6,6 +6,7 @@ typedef scf_node_t scf_expr_t; // expr is a node scf_expr_t* scf_expr_alloc(); +scf_expr_t* scf_expr_clone(scf_expr_t* e); void scf_expr_free(scf_expr_t* expr); int scf_expr_add_node(scf_expr_t* expr, scf_node_t* node); diff --git a/core/scf_lex_word.h b/core/scf_lex_word.h index 076baad..c25212b 100644 --- a/core/scf_lex_word.h +++ b/core/scf_lex_word.h @@ -77,18 +77,27 @@ enum scf_lex_words { SCF_LEX_WORD_KEY_ELSIF, // else if SCF_LEX_WORD_KEY_END_IF, // end if - SCF_LEX_WORD_KEY_FOR, // for - SCF_LEX_WORD_KEY_WHILE, // while + SCF_LEX_WORD_KEY_FOR, // for + SCF_LEX_WORD_KEY_TO, // to + SCF_LEX_WORD_KEY_BY, // by + SCF_LEX_WORD_KEY_DO, // do + SCF_LEX_WORD_KEY_END_FOR, // end for + + SCF_LEX_WORD_KEY_WHILE, // while + SCF_LEX_WORD_KEY_END_WHILE, // end while SCF_LEX_WORD_KEY_REPEAT, // repeat SCF_LEX_WORD_KEY_UNTIL, // until + SCF_LEX_WORD_KEY_END_REPEAT,// - SCF_LEX_WORD_KEY_BREAK, // break - SCF_LEX_WORD_KEY_CONTINUE, // continue + SCF_LEX_WORD_KEY_BREAK, // break + SCF_LEX_WORD_KEY_CONTINUE, // continue + SCF_LEX_WORD_KEY_EXIT, // exit SCF_LEX_WORD_KEY_SWITCH, // switch SCF_LEX_WORD_KEY_CASE, // case SCF_LEX_WORD_KEY_DEFAULT, // default + SCF_LEX_WORD_KEY_END_CASE, // end case SCF_LEX_WORD_KEY_RETURN, // return @@ -100,6 +109,10 @@ enum scf_lex_words { SCF_LEX_WORD_KEY_CREATE, // create class object SCF_LEX_WORD_KEY_CONTAINER, // container_of + SCF_LEX_WORD_KEY_OF, // of + SCF_LEX_WORD_KEY_AT, // at + SCF_LEX_WORD_KEY_EN, // enable + SCF_LEX_WORD_KEY_ENO, // enable output SCF_LEX_WORD_KEY_OPERATOR, // operator @@ -111,11 +124,11 @@ enum scf_lex_words { SCF_LEX_WORD_KEY_CHAR, // char SCF_LEX_WORD_KEY_BIT, // bit - SCF_LEX_WORD_ST_TIME, // time - SCF_LEX_WORD_ST_TIME_OF_DATE, // time of date - SCF_LEX_WORD_ST_DATE, // date - SCF_LEX_WORD_ST_DATE_AND_TIME, // date and time - SCF_LEX_WORD_ST_STRING, // string + SCF_LEX_WORD_KEY_TIME, // time + SCF_LEX_WORD_KEY_TIME_OF_DATE, // time of date + SCF_LEX_WORD_KEY_DATE, // date + SCF_LEX_WORD_KEY_DATE_AND_TIME, // date and time + SCF_LEX_WORD_KEY_STRING, // string SCF_LEX_WORD_KEY_INT, // int SCF_LEX_WORD_KEY_FLOAT, // float @@ -154,8 +167,38 @@ enum scf_lex_words { SCF_LEX_WORD_KEY_UNION, // union SCF_LEX_WORD_KEY_STRUCT, // struct + SCF_LEX_WORD_KEY_END_STRUCT,// end struct SCF_LEX_WORD_KEY_ARRAY, // array - SCF_LEX_WORD_KEY_OF, // of + + SCF_LEX_WORD_KEY_TASK, // task + + SCF_LEX_WORD_KEY_TON, // ton + SCF_LEX_WORD_KEY_F_TRIG, // f trig + + SCF_LEX_WORD_KEY_CONFIG, // config + SCF_LEX_WORD_KEY_END_CONFIG, // end config + + SCF_LEX_WORD_KEY_RESOURCE, // config + SCF_LEX_WORD_KEY_END_RESOURCE, // end config + + SCF_LEX_WORD_KEY_PROGRAM, // program + SCF_LEX_WORD_KEY_END_PROGRAM, + + SCF_LEX_WORD_KEY_FUNCTION, // function + SCF_LEX_WORD_KEY_END_FUNCTION, + + SCF_LEX_WORD_KEY_FUNCTION_BLOCK, // function block + SCF_LEX_WORD_KEY_END_FUNCTION_BLOCK, + + SCF_LEX_WORD_KEY_VAR, // var + SCF_LEX_WORD_KEY_VAR_INPUT, // var input + SCF_LEX_WORD_KEY_VAR_OUTPUT, // var output + SCF_LEX_WORD_KEY_VAR_IN_OUT, // var in out + SCF_LEX_WORD_KEY_VAR_GLOBAL, // var global + SCF_LEX_WORD_KEY_VAR_EXTERNAL, // var external + SCF_LEX_WORD_KEY_VAR_TEMP, // var temp + SCF_LEX_WORD_KEY_VAR_CONSTANT, // var const + SCF_LEX_WORD_KEY_END_VAR, // const literal value SCF_LEX_WORD_CONST_CHAR, diff --git a/core/scf_node.c b/core/scf_node.c index c745e35..eafdcba 100644 --- a/core/scf_node.c +++ b/core/scf_node.c @@ -64,6 +64,57 @@ _failed: return NULL; } +scf_node_t* scf_node_clone(scf_node_t* node) +{ + scf_node_t* node2 = calloc(1, sizeof(scf_node_t)); + if (!node2) + return NULL; + + if (scf_type_is_var(node->type)) { + + node2->var = scf_variable_ref(node->var); + if (!node2->var) + goto _failed; + + } else if (SCF_LABEL == node->type) { + node2->label = node->label; + + } else { + if (node->w) { + node2->w = scf_lex_word_clone(node->w); + if (!node2->w) + goto _failed; + + } else + node2->w = NULL; + } + + if (node->debug_w) { + node2->debug_w = scf_lex_word_clone(node->debug_w); + + if (!node2->debug_w) + goto _failed; + } + + node2->type = node->type; + + node2->root_flag = node->root_flag; + node2->file_flag = node->file_flag; + node2->class_flag = node->class_flag; + node2->union_flag = node->union_flag; + node2->define_flag = node->define_flag; + node2->const_flag = node->const_flag; + node2->split_flag = node->split_flag; + node2->semi_flag = node->semi_flag; + + scf_logd("node: %p, node->type: %d\n", node, node->type); + return node; + +_failed: + scf_node_free(node); + return NULL; +} + scf_node_t* scf_node_alloc_label(scf_label_t* l) { scf_node_t* node = calloc(1, sizeof(scf_node_t)); diff --git a/core/scf_node.h b/core/scf_node.h index 3cff852..edde26f 100644 --- a/core/scf_node.h +++ b/core/scf_node.h @@ -61,6 +61,8 @@ struct scf_label_s { scf_node_t* scf_node_alloc(scf_lex_word_t* w, int type, scf_variable_t* var); scf_node_t* scf_node_alloc_label(scf_label_t* l); +scf_node_t* scf_node_clone(scf_node_t* node); + int scf_node_add_child(scf_node_t* parent, scf_node_t* child); void scf_node_free(scf_node_t* node); diff --git a/core/scf_operator.c b/core/scf_operator.c index d9e74d6..68412dc 100644 --- a/core/scf_operator.c +++ b/core/scf_operator.c @@ -74,6 +74,7 @@ static scf_operator_t base_operators[] = { {SCF_OP_IF, "if", 15, -1, SCF_OP_ASSOCIATIVITY_LEFT}, {SCF_OP_WHILE, "while", 15, -1, SCF_OP_ASSOCIATIVITY_LEFT}, + {SCF_OP_REPEAT, "repeat", 15, -1, SCF_OP_ASSOCIATIVITY_LEFT}, {SCF_OP_FOR, "for", 15, -1, SCF_OP_ASSOCIATIVITY_LEFT}, }; diff --git a/core/scf_operator_handler_3ac.c b/core/scf_operator_handler_3ac.c index 6d2ddf2..e102e6d 100644 --- a/core/scf_operator_handler_3ac.c +++ b/core/scf_operator_handler_3ac.c @@ -1121,6 +1121,66 @@ static int _scf_op_end_loop(scf_list_t* start_prev, scf_list_t* continue_prev, s return 0; } +static int _scf_op_repeat(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* data) +{ + assert(2 == nb_nodes); + + scf_handler_data_t* d = data; + scf_expr_t* e = nodes[1]; + + assert(SCF_OP_EXPR == e->type); + + scf_list_t* start_prev = scf_list_tail(d->_3ac_list_head); + + int jmp_op = _scf_op_cond(ast, e, d); + if (jmp_op < 0) { + scf_loge("\n"); + return -1; + } + + scf_list_t* l; + scf_3ac_code_t* c; + scf_3ac_code_t* jmp_end = scf_branch_ops_code(jmp_op, NULL, NULL); + + scf_list_add_tail(d->_3ac_list_head, &jmp_end->list); + + scf_branch_ops_t* local_branch_ops = scf_branch_ops_alloc(); + scf_branch_ops_t* up_branch_ops = d->branch_ops; + d->branch_ops = local_branch_ops; + + if (_scf_op_node(ast, nodes[0], d) < 0) { + scf_loge("\n"); + return -1; + } + + if (_scf_op_end_loop(start_prev, NULL, jmp_end, up_branch_ops, d) < 0) { + scf_loge("\n"); + return -1; + } + + d->branch_ops = up_branch_ops; + scf_branch_ops_free(local_branch_ops); + local_branch_ops = NULL; + + // delete 'cond check' at 'start of loop' + scf_vector_del(d->branch_ops->_breaks, jmp_end); + + for (l = scf_list_next(start_prev); l != &jmp_end->list; ) { + c = scf_list_data(l, scf_3ac_code_t, list); + l = scf_list_next(l); + + scf_list_del(&c->list); + scf_3ac_code_free(c); + c = NULL; + } + + scf_list_del(&jmp_end->list); + scf_3ac_code_free(jmp_end); + jmp_end = NULL; + + return 0; +} + static int _scf_op_while(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* data) { assert(2 == nb_nodes || 1 == nb_nodes); @@ -1130,8 +1190,6 @@ static int _scf_op_while(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* scf_expr_t* e = nodes[0]; assert(SCF_OP_EXPR == e->type); - scf_block_t* b = (scf_block_t*)(e->parent); - // we don't know the real start of the while loop here, // we only know it's the next of 'start_prev' scf_list_t* start_prev = scf_list_tail(d->_3ac_list_head); @@ -2494,6 +2552,7 @@ scf_operator_handler_t _3ac_operator_handlers[] = { {{NULL, NULL}, SCF_OP_IF, -1, -1, -1, _scf_op_if}, {{NULL, NULL}, SCF_OP_WHILE, -1, -1, -1, _scf_op_while}, + {{NULL, NULL}, SCF_OP_REPEAT, -1, -1, -1, _scf_op_repeat}, {{NULL, NULL}, SCF_OP_FOR, -1, -1, -1, _scf_op_for}, }; diff --git a/core/scf_type.c b/core/scf_type.c index f8eabfe..cb3313c 100644 --- a/core/scf_type.c +++ b/core/scf_type.c @@ -16,7 +16,7 @@ scf_type_t* scf_type_alloc(scf_lex_word_t* w, const char* name, int type, int si else t->w = NULL; - t->size = size; + t->size = size; return t; } diff --git a/core/scf_variable.h b/core/scf_variable.h index 04d39de..cbb09f3 100644 --- a/core/scf_variable.h +++ b/core/scf_variable.h @@ -57,6 +57,9 @@ struct scf_variable_s { uint32_t arg_flag :1; uint32_t auto_gc_flag:1; + + uint32_t input_flag :1; + uint32_t output_flag :1; }; struct scf_index_s diff --git a/lex/scf_lex.c b/lex/scf_lex.c index 6564aba..3fbd2f7 100644 --- a/lex/scf_lex.c +++ b/lex/scf_lex.c @@ -6,6 +6,7 @@ static scf_lex_key_word_t key_words[] = { {"for", SCF_LEX_WORD_KEY_FOR}, {"while", SCF_LEX_WORD_KEY_WHILE}, + {"do", SCF_LEX_WORD_KEY_DO}, {"break", SCF_LEX_WORD_KEY_BREAK}, {"continue", SCF_LEX_WORD_KEY_CONTINUE}, diff --git a/parse/Makefile b/parse/Makefile index 7d5c6aa..7ea14d6 100644 --- a/parse/Makefile +++ b/parse/Makefile @@ -4,8 +4,7 @@ CFILES += ../lex/scf_lex.c CFILES += ../lex/scf_lex_util.c CFILES += scf_parse_util.c -#CFILES += scf_parse.c -CFILES += scf_parse2.c +CFILES += scf_parse.c CFILES += main.c CFILES += scf_operator_handler_semantic.c CFILES += scf_operator_handler_expr.c @@ -148,6 +147,7 @@ CFILES += scf_struct_array.c CFILES += scf_dfa_if.c CFILES += scf_dfa_while.c +CFILES += scf_dfa_repeat.c CFILES += scf_dfa_for.c CFILES += scf_dfa_break.c diff --git a/parse/scf_dfa.c b/parse/scf_dfa.c index f38a7fa..8d7c10a 100644 --- a/parse/scf_dfa.c +++ b/parse/scf_dfa.c @@ -277,7 +277,7 @@ static int _scf_dfa_childs_parse_word(scf_dfa_t* dfa, scf_dfa_node_t** childs, i continue; } - scf_logi("pre hook: %s\n", hook->node->name); + scf_logi("\033[32mpre hook: %s\033[0m\n", hook->node->name); // delete all hooks before it, and itself. scf_dfa_clear_hooks(&(dfa->hooks[SCF_DFA_HOOK_PRE]), hook->next); diff --git a/parse/scf_dfa.h b/parse/scf_dfa.h index 20f92ad..6dc8fc5 100644 --- a/parse/scf_dfa.h +++ b/parse/scf_dfa.h @@ -99,6 +99,11 @@ static inline int scf_dfa_action_entry(scf_dfa_t* dfa, scf_vector_t* words, void return words->size > 0 ? SCF_DFA_CONTINUE : SCF_DFA_NEXT_WORD; } +static inline int scf_dfa_action_next(scf_dfa_t* dfa, scf_vector_t* words, void* data) +{ + return SCF_DFA_NEXT_WORD; +} + #define SCF_DFA_MODULE_NODE(dfa, module, node, is, action) \ { \ char str[256]; \ diff --git a/parse/scf_dfa_block.c b/parse/scf_dfa_block.c index 7c20393..20600ae 100644 --- a/parse/scf_dfa_block.c +++ b/parse/scf_dfa_block.c @@ -150,6 +150,7 @@ static int _dfa_init_module_block(scf_dfa_t* dfa) SCF_DFA_GET_MODULE_NODE(dfa, if, _if, _if); SCF_DFA_GET_MODULE_NODE(dfa, while, _while, _while); + SCF_DFA_GET_MODULE_NODE(dfa, repeat, _do, _do); SCF_DFA_GET_MODULE_NODE(dfa, for, _for, _for); SCF_DFA_GET_MODULE_NODE(dfa, break, _break, _break); @@ -174,6 +175,7 @@ static int _dfa_init_module_block(scf_dfa_t* dfa) scf_dfa_node_add_child(entry, _if); scf_dfa_node_add_child(entry, _while); + scf_dfa_node_add_child(entry, _do); scf_dfa_node_add_child(entry, _for); scf_dfa_node_add_child(entry, _break); diff --git a/parse/scf_dfa_parse.c b/parse/scf_dfa_parse.c index 0367ec1..dcfee6a 100644 --- a/parse/scf_dfa_parse.c +++ b/parse/scf_dfa_parse.c @@ -1,6 +1,147 @@ #include"scf_dfa.h" #include"scf_parse.h" +extern scf_dfa_module_t dfa_module_include; + +extern scf_dfa_module_t dfa_module_identity; + +extern scf_dfa_module_t dfa_module_expr; +extern scf_dfa_module_t dfa_module_create; +extern scf_dfa_module_t dfa_module_call; +extern scf_dfa_module_t dfa_module_sizeof; +extern scf_dfa_module_t dfa_module_container; +extern scf_dfa_module_t dfa_module_init_data; +extern scf_dfa_module_t dfa_module_va_arg; + +extern scf_dfa_module_t dfa_module_union; +extern scf_dfa_module_t dfa_module_class; + +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_operator; + +extern scf_dfa_module_t dfa_module_if; +extern scf_dfa_module_t dfa_module_while; +extern scf_dfa_module_t dfa_module_repeat; +extern scf_dfa_module_t dfa_module_for; + +#if 1 +extern scf_dfa_module_t dfa_module_break; +extern scf_dfa_module_t dfa_module_continue; +extern scf_dfa_module_t dfa_module_return; +extern scf_dfa_module_t dfa_module_goto; +extern scf_dfa_module_t dfa_module_label; +extern scf_dfa_module_t dfa_module_error; +extern scf_dfa_module_t dfa_module_async; +#endif +extern scf_dfa_module_t dfa_module_block; + +scf_dfa_module_t* dfa_modules[] = +{ + &dfa_module_include, + + &dfa_module_identity, + + &dfa_module_expr, + &dfa_module_create, + &dfa_module_call, + &dfa_module_sizeof, + &dfa_module_container, + &dfa_module_init_data, + &dfa_module_va_arg, + + &dfa_module_union, + &dfa_module_class, + + &dfa_module_type, + + &dfa_module_var, + + &dfa_module_function, + &dfa_module_operator, + + &dfa_module_if, + &dfa_module_while, + &dfa_module_repeat, + &dfa_module_for, + +#if 1 + &dfa_module_break, + &dfa_module_continue, + &dfa_module_goto, + &dfa_module_return, + &dfa_module_label, + &dfa_module_error, + &dfa_module_async, +#endif + &dfa_module_block, +}; + +int scf_parse_dfa_init(scf_parse_t* parse) +{ + if (scf_dfa_open(&parse->dfa, "parse", parse) < 0) { + scf_loge("\n"); + return -1; + } + + int nb_modules = sizeof(dfa_modules) / sizeof(dfa_modules[0]); + + parse->dfa_data = calloc(1, sizeof(dfa_parse_data_t)); + if (!parse->dfa_data) { + scf_loge("\n"); + return -1; + } + + parse->dfa_data->module_datas = calloc(nb_modules, sizeof(void*)); + if (!parse->dfa_data->module_datas) { + scf_loge("\n"); + return -1; + } + + parse->dfa_data->current_identities = scf_stack_alloc(); + if (!parse->dfa_data->current_identities) { + scf_loge("\n"); + return -1; + } + + int i; + for (i = 0; i < nb_modules; i++) { + + scf_dfa_module_t* m = dfa_modules[i]; + + if (!m) + continue; + + m->index = i; + + if (!m->init_module) + continue; + + if (m->init_module(parse->dfa) < 0) { + scf_loge("init module: %s\n", m->name); + return -1; + } + } + + for (i = 0; i < nb_modules; i++) { + + scf_dfa_module_t* m = dfa_modules[i]; + + if (!m || !m->init_syntax) + continue; + + if (m->init_syntax(parse->dfa) < 0) { + scf_loge("init syntax: %s\n", m->name); + return -1; + } + } + + return 0; +} + static void* dfa_pop_word(scf_dfa_t* dfa) { scf_parse_t* parse = dfa->priv; diff --git a/parse/scf_dfa_repeat.c b/parse/scf_dfa_repeat.c new file mode 100644 index 0000000..15ee163 --- /dev/null +++ b/parse/scf_dfa_repeat.c @@ -0,0 +1,232 @@ +#include"scf_dfa.h" +#include"scf_dfa_util.h" +#include"scf_parse.h" +#include"scf_stack.h" + +extern scf_dfa_module_t dfa_module_repeat; + +typedef struct { + int nb_lps; + int nb_rps; + + scf_block_t* parent_block; + scf_node_t* parent_node; + + scf_node_t* repeat; + + scf_dfa_hook_t* hook_end; + +} dfa_repeat_data_t; + + +static int _repeat_action_do(scf_dfa_t* dfa, scf_vector_t* words, void* data) +{ + scf_parse_t* parse = dfa->priv; + dfa_parse_data_t* d = data; + scf_lex_word_t* w = words->data[words->size - 1]; + scf_stack_t* s = d->module_datas[dfa_module_repeat.index]; + scf_block_t* b = NULL; + + scf_node_t* repeat = scf_node_alloc(w, SCF_OP_REPEAT, NULL); + if (!repeat) { + scf_loge("node alloc failed\n"); + return SCF_DFA_ERROR; + } + + dfa_repeat_data_t* rd = calloc(1, sizeof(dfa_repeat_data_t)); + if (!rd) { + scf_loge("module data alloc failed\n"); + return SCF_DFA_ERROR; + } + + if (d->current_node) + scf_node_add_child(d->current_node, repeat); + else + scf_node_add_child((scf_node_t*)parse->ast->current_block, repeat); + + rd->repeat = repeat; + rd->parent_block = parse->ast->current_block; + rd->parent_node = d->current_node; + d->current_node = repeat; + + scf_stack_push(s, rd); + + SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "repeat__while"), SCF_DFA_HOOK_END); + + return SCF_DFA_NEXT_WORD; +} + +static int _repeat_action_while(scf_dfa_t* dfa, scf_vector_t* words, void* data) +{ + scf_lex_word_t* w = dfa->ops->pop_word(dfa); + + if (SCF_LEX_WORD_KEY_WHILE != w->type) + return SCF_DFA_ERROR; + + return SCF_DFA_SWITCH_TO; +} + +static int _repeat_action_lp(scf_dfa_t* dfa, scf_vector_t* words, void* data) +{ + scf_parse_t* parse = dfa->priv; + dfa_parse_data_t* d = data; + scf_lex_word_t* w = words->data[words->size - 1]; + scf_stack_t* s = d->module_datas[dfa_module_repeat.index]; + dfa_repeat_data_t* rd = scf_stack_top(s); + + assert(!d->expr); + d->expr_local_flag = 1; + + SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "repeat_rp"), SCF_DFA_HOOK_POST); + SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "repeat_lp_stat"), SCF_DFA_HOOK_POST); + + return SCF_DFA_NEXT_WORD; +} + +static int _repeat_action_lp_stat(scf_dfa_t* dfa, scf_vector_t* words, void* data) +{ + dfa_parse_data_t* d = data; + scf_stack_t* s = d->module_datas[dfa_module_repeat.index]; + dfa_repeat_data_t* rd = scf_stack_top(s); + + SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "repeat_lp_stat"), SCF_DFA_HOOK_POST); + + rd->nb_lps++; + + return SCF_DFA_NEXT_WORD; +} + +static int _repeat_action_rp(scf_dfa_t* dfa, scf_vector_t* words, void* data) +{ + scf_parse_t* parse = dfa->priv; + dfa_parse_data_t* d = data; + scf_lex_word_t* w = words->data[words->size - 1]; + scf_stack_t* s = d->module_datas[dfa_module_repeat.index]; + dfa_repeat_data_t* rd = scf_stack_top(s); + + if (!d->expr) { + scf_loge("\n"); + return SCF_DFA_ERROR; + } + + rd->nb_rps++; + + if (rd->nb_rps == rd->nb_lps) { + + assert(1 == rd->repeat->nb_nodes); + + scf_node_add_child(rd->repeat, d->expr); + d->expr = NULL; + + d->expr_local_flag = 0; + + return SCF_DFA_SWITCH_TO; + } + + SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "repeat_rp"), SCF_DFA_HOOK_POST); + SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "repeat_lp_stat"), SCF_DFA_HOOK_POST); + + return SCF_DFA_NEXT_WORD; +} + +static int _repeat_action_semicolon(scf_dfa_t* dfa, scf_vector_t* words, void* data) +{ + scf_parse_t* parse = dfa->priv; + dfa_parse_data_t* d = data; + scf_stack_t* s = d->module_datas[dfa_module_repeat.index]; + dfa_repeat_data_t* rd = scf_stack_pop(s); + + assert(parse->ast->current_block == rd->parent_block); + + d->current_node = rd->parent_node; + + scf_logi("\033[31m repeat: %d, rd: %p, s->size: %d\033[0m\n", rd->repeat->w->line, rd, s->size); + + free(rd); + rd = NULL; + + assert(s->size >= 0); + + return SCF_DFA_OK; +} + +static int _dfa_init_module_repeat(scf_dfa_t* dfa) +{ + SCF_DFA_MODULE_NODE(dfa, repeat, semicolon, scf_dfa_is_semicolon, _repeat_action_semicolon); + + SCF_DFA_MODULE_NODE(dfa, repeat, lp, scf_dfa_is_lp, _repeat_action_lp); + SCF_DFA_MODULE_NODE(dfa, repeat, rp, scf_dfa_is_rp, _repeat_action_rp); + SCF_DFA_MODULE_NODE(dfa, repeat, lp_stat, scf_dfa_is_lp, _repeat_action_lp_stat); + + SCF_DFA_MODULE_NODE(dfa, repeat, _do, scf_dfa_is_do, _repeat_action_do); + SCF_DFA_MODULE_NODE(dfa, repeat, _while, scf_dfa_is_while, _repeat_action_while); + + scf_parse_t* parse = dfa->priv; + dfa_parse_data_t* d = parse->dfa_data; + scf_stack_t* s = d->module_datas[dfa_module_repeat.index]; + + assert(!s); + + s = scf_stack_alloc(); + if (!s) { + scf_logi("\n"); + return SCF_DFA_ERROR; + } + + d->module_datas[dfa_module_repeat.index] = s; + + return SCF_DFA_OK; +} + +static int _dfa_fini_module_repeat(scf_dfa_t* dfa) +{ + scf_parse_t* parse = dfa->priv; + dfa_parse_data_t* d = parse->dfa_data; + scf_stack_t* s = d->module_datas[dfa_module_repeat.index]; + + if (s) { + scf_stack_free(s); + s = NULL; + d->module_datas[dfa_module_repeat.index] = NULL; + } + + return SCF_DFA_OK; +} + +static int _dfa_init_syntax_repeat(scf_dfa_t* dfa) +{ + SCF_DFA_GET_MODULE_NODE(dfa, repeat, lp, lp); + SCF_DFA_GET_MODULE_NODE(dfa, repeat, rp, rp); + SCF_DFA_GET_MODULE_NODE(dfa, repeat, lp_stat, lp_stat); + SCF_DFA_GET_MODULE_NODE(dfa, repeat, _do, _do); + SCF_DFA_GET_MODULE_NODE(dfa, repeat, _while, _while); + SCF_DFA_GET_MODULE_NODE(dfa, repeat, semicolon, semicolon); + + SCF_DFA_GET_MODULE_NODE(dfa, expr, entry, expr); + SCF_DFA_GET_MODULE_NODE(dfa, block, entry, block); + + // repeat start + scf_vector_add(dfa->syntaxes, _do); + + scf_dfa_node_add_child(_do, block); + scf_dfa_node_add_child(block, _while); + + scf_dfa_node_add_child(_while, lp); + scf_dfa_node_add_child(lp, expr); + scf_dfa_node_add_child(expr, rp); + scf_dfa_node_add_child(rp, semicolon); + + scf_logi("\n"); + return 0; +} + +scf_dfa_module_t dfa_module_repeat = +{ + .name = "repeat", + + .init_module = _dfa_init_module_repeat, + .init_syntax = _dfa_init_syntax_repeat, + + .fini_module = _dfa_fini_module_repeat, +}; + diff --git a/parse/scf_dfa_util.h b/parse/scf_dfa_util.h index 38e1dbb..9149960 100644 --- a/parse/scf_dfa_util.h +++ b/parse/scf_dfa_util.h @@ -46,6 +46,13 @@ static inline int scf_dfa_is_rb(scf_dfa_t* dfa, void* word) return SCF_LEX_WORD_RB == w->type; } +static inline int scf_dfa_is_range(scf_dfa_t* dfa, void* word) +{ + scf_lex_word_t* w = word; + + return SCF_LEX_WORD_RANGE == w->type; +} + static inline int scf_dfa_is_comma(scf_dfa_t* dfa, void* word) { scf_lex_word_t* w = word; @@ -60,6 +67,20 @@ static inline int scf_dfa_is_semicolon(scf_dfa_t* dfa, void* word) return SCF_LEX_WORD_SEMICOLON == w->type; } +static inline int scf_dfa_is_end_struct(scf_dfa_t* dfa, void* word) +{ + scf_lex_word_t* w = word; + + return SCF_LEX_WORD_KEY_END_STRUCT == w->type; +} + +static inline int scf_dfa_is_colon(scf_dfa_t* dfa, void* word) +{ + scf_lex_word_t* w = word; + + return SCF_LEX_WORD_COLON == w->type; +} + static inline int scf_dfa_is_star(scf_dfa_t* dfa, void* word) { scf_lex_word_t* w = word; @@ -67,6 +88,27 @@ static inline int scf_dfa_is_star(scf_dfa_t* dfa, void* word) return SCF_LEX_WORD_STAR == w->type; } +static inline int scf_dfa_is_assign(scf_dfa_t* dfa, void* word) +{ + scf_lex_word_t* w = word; + + return SCF_LEX_WORD_ASSIGN == w->type; +} + +static inline int scf_dfa_is_array(scf_dfa_t* dfa, void* word) +{ + scf_lex_word_t* w = word; + + return SCF_LEX_WORD_KEY_ARRAY == w->type; +} + +static inline int scf_dfa_is_of(scf_dfa_t* dfa, void* word) +{ + scf_lex_word_t* w = word; + + return SCF_LEX_WORD_KEY_OF == w->type; +} + static inline int scf_dfa_is_identity(scf_dfa_t* dfa, void* word) { scf_lex_word_t* w = word; @@ -158,5 +200,201 @@ static inline int scf_dfa_is_const_string(scf_dfa_t* dfa, void* word) return SCF_LEX_WORD_CONST_STRING == w->type; } +static inline int scf_dfa_is_if(scf_dfa_t* dfa, void* word) +{ + scf_lex_word_t* w = word; + + return SCF_LEX_WORD_KEY_IF == w->type; +} + +static inline int scf_dfa_is_else(scf_dfa_t* dfa, void* word) +{ + scf_lex_word_t* w = word; + + return SCF_LEX_WORD_KEY_ELSE == w->type; +} + +static inline int scf_dfa_is_then(scf_dfa_t* dfa, void* word) +{ + scf_lex_word_t* w = word; + + return SCF_LEX_WORD_KEY_THEN == w->type; +} + +static inline int scf_dfa_is_elsif(scf_dfa_t* dfa, void* word) +{ + scf_lex_word_t* w = word; + + return SCF_LEX_WORD_KEY_ELSIF == w->type; +} + +static inline int scf_dfa_is_end_if(scf_dfa_t* dfa, void* word) +{ + scf_lex_word_t* w = word; + + return SCF_LEX_WORD_KEY_END_IF == w->type; +} + +static inline int scf_dfa_is_while(scf_dfa_t* dfa, void* word) +{ + scf_lex_word_t* w = word; + + return SCF_LEX_WORD_KEY_WHILE == w->type; +} + +static inline int scf_dfa_is_do(scf_dfa_t* dfa, void* word) +{ + scf_lex_word_t* w = word; + + return SCF_LEX_WORD_KEY_DO == w->type; +} + +static inline int scf_dfa_is_to(scf_dfa_t* dfa, void* word) +{ + scf_lex_word_t* w = word; + + return SCF_LEX_WORD_KEY_TO == w->type; +} + +static inline int scf_dfa_is_by(scf_dfa_t* dfa, void* word) +{ + scf_lex_word_t* w = word; + + return SCF_LEX_WORD_KEY_BY == w->type; +} + +static inline int scf_dfa_is_end_while(scf_dfa_t* dfa, void* word) +{ + scf_lex_word_t* w = word; + + return SCF_LEX_WORD_KEY_END_WHILE == w->type; +} + +static inline int scf_dfa_is_for(scf_dfa_t* dfa, void* word) +{ + scf_lex_word_t* w = word; + + return SCF_LEX_WORD_KEY_FOR == w->type; +} + +static inline int scf_dfa_is_end_for(scf_dfa_t* dfa, void* word) +{ + scf_lex_word_t* w = word; + + return SCF_LEX_WORD_KEY_END_FOR == w->type; +} + +static inline int scf_dfa_is_case(scf_dfa_t* dfa, void* word) +{ + scf_lex_word_t* w = word; + + return SCF_LEX_WORD_KEY_CASE == w->type; +} + +static inline int scf_dfa_is_end_case(scf_dfa_t* dfa, void* word) +{ + scf_lex_word_t* w = word; + + return SCF_LEX_WORD_KEY_END_CASE == w->type; +} + +static inline int scf_dfa_is_repeat(scf_dfa_t* dfa, void* word) +{ + scf_lex_word_t* w = word; + + return SCF_LEX_WORD_KEY_REPEAT == w->type; +} + +static inline int scf_dfa_is_until(scf_dfa_t* dfa, void* word) +{ + scf_lex_word_t* w = word; + + return SCF_LEX_WORD_KEY_UNTIL == w->type; +} + +static inline int scf_dfa_is_end_repeat(scf_dfa_t* dfa, void* word) +{ + scf_lex_word_t* w = word; + + return SCF_LEX_WORD_KEY_END_REPEAT == w->type; +} + +static inline int scf_dfa_is_function(scf_dfa_t* dfa, void* word) +{ + scf_lex_word_t* w = word; + + return SCF_LEX_WORD_KEY_FUNCTION == w->type; +} + +static inline int scf_dfa_is_end_function(scf_dfa_t* dfa, void* word) +{ + scf_lex_word_t* w = word; + + return SCF_LEX_WORD_KEY_END_FUNCTION == w->type; +} + +static inline int scf_dfa_is_var(scf_dfa_t* dfa, void* word) +{ + scf_lex_word_t* w = word; + + return SCF_LEX_WORD_KEY_VAR == w->type; +} + +static inline int scf_dfa_is_var_input(scf_dfa_t* dfa, void* word) +{ + scf_lex_word_t* w = word; + + return SCF_LEX_WORD_KEY_VAR_INPUT == w->type; +} + +static inline int scf_dfa_is_var_output(scf_dfa_t* dfa, void* word) +{ + scf_lex_word_t* w = word; + + return SCF_LEX_WORD_KEY_VAR_OUTPUT == w->type; +} + +static inline int scf_dfa_is_var_in_out(scf_dfa_t* dfa, void* word) +{ + scf_lex_word_t* w = word; + + return SCF_LEX_WORD_KEY_VAR_IN_OUT == w->type; +} + +static inline int scf_dfa_is_var_temp(scf_dfa_t* dfa, void* word) +{ + scf_lex_word_t* w = word; + + return SCF_LEX_WORD_KEY_VAR_TEMP == w->type; +} + +static inline int scf_dfa_is_var_const(scf_dfa_t* dfa, void* word) +{ + scf_lex_word_t* w = word; + + return SCF_LEX_WORD_KEY_VAR_CONSTANT == w->type; +} + +static inline int scf_dfa_is_var_global(scf_dfa_t* dfa, void* word) +{ + scf_lex_word_t* w = word; + + return SCF_LEX_WORD_KEY_VAR_GLOBAL == w->type; +} + +static inline int scf_dfa_is_var_external(scf_dfa_t* dfa, void* word) +{ + scf_lex_word_t* w = word; + + return SCF_LEX_WORD_KEY_VAR_EXTERNAL == w->type; +} + +static inline int scf_dfa_is_end_var(scf_dfa_t* dfa, void* word) +{ + scf_lex_word_t* w = word; + + return SCF_LEX_WORD_KEY_END_VAR == w->type; +} + #endif diff --git a/parse/scf_operator_handler_const.c b/parse/scf_operator_handler_const.c index 809ed8b..db210e0 100644 --- a/parse/scf_operator_handler_const.c +++ b/parse/scf_operator_handler_const.c @@ -355,6 +355,25 @@ static int _scf_op_const_if(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, vo return 0; } +static int _scf_op_const_repeat(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* data) +{ + assert(2 == nb_nodes); + + scf_handler_data_t* d = data; + scf_variable_t* r = NULL; + scf_expr_t* e = nodes[1]; + + assert(SCF_OP_EXPR == e->type); + + if (_scf_op_const_node(ast, nodes[1], d) < 0) + return -1; + + if (_scf_expr_calculate_internal(ast, e, &r) < 0) + return -1; + + return 0; +} + static int _scf_op_const_while(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* data) { assert(2 == nb_nodes || 1 == nb_nodes); @@ -1000,8 +1019,9 @@ scf_operator_handler_t const_operator_handlers[] = { {{NULL, NULL}, SCF_LABEL, -1, -1, -1, _scf_op_const_label}, {{NULL, NULL}, SCF_OP_ERROR, -1, -1, -1, _scf_op_const_error}, - {{NULL, NULL}, SCF_OP_IF, -1, -1, -1, _scf_op_const_if}, - {{NULL, NULL}, SCF_OP_WHILE, -1, -1, -1, _scf_op_const_while}, + {{NULL, NULL}, SCF_OP_IF, -1, -1, -1, _scf_op_const_if}, + {{NULL, NULL}, SCF_OP_WHILE, -1, -1, -1, _scf_op_const_while}, + {{NULL, NULL}, SCF_OP_REPEAT, -1, -1, -1, _scf_op_const_repeat}, {{NULL, NULL}, SCF_OP_FOR, -1, -1, -1, _scf_op_const_for}, }; diff --git a/parse/scf_operator_handler_semantic.c b/parse/scf_operator_handler_semantic.c index 7212141..d39748c 100644 --- a/parse/scf_operator_handler_semantic.c +++ b/parse/scf_operator_handler_semantic.c @@ -1327,18 +1327,69 @@ static int _scf_op_semantic_if(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, return 0; } +static int _scf_op_semantic_repeat(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* data) +{ + assert(2 == nb_nodes); + + scf_handler_data_t* d = data; + scf_variable_t* r = NULL; + scf_node_t* node = nodes[0]; + scf_expr_t* e = nodes[1]; + scf_operator_t* op = node->op; + + assert(SCF_OP_EXPR == e->type); + + if (!op) { + op = scf_find_base_operator_by_type(node->type); + if (!op) { + scf_loge("\n"); + return -1; + } + } + + scf_variable_t** pret = d->pret; + + scf_operator_handler_t* h = scf_find_semantic_operator_handler(op->type, -1, -1, -1); + if (!h) { + scf_loge("\n"); + return -1; + } + + d->pret = &node->result; + int ret = h->func(ast, node->nodes, node->nb_nodes, d); + d->pret = pret; + + if (ret < 0) { + scf_loge("\n"); + return -1; + } + + if (_scf_expr_calculate(ast, e, &r) < 0) { + scf_loge("\n"); + return -1; + } + + if (!r || !scf_variable_interger(r)) { + scf_loge("\n"); + return -1; + } + + scf_variable_free(r); + r = NULL; + + return 0; +} + static int _scf_op_semantic_while(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* data) { assert(2 == nb_nodes || 1 == nb_nodes); scf_handler_data_t* d = data; + scf_variable_t* r = NULL; + scf_expr_t* e = nodes[0]; - scf_expr_t* e = nodes[0]; assert(SCF_OP_EXPR == e->type); - scf_block_t* b = (scf_block_t*)(e->parent); - - scf_variable_t* r = NULL; if (_scf_expr_calculate(ast, e, &r) < 0) { scf_loge("\n"); return -1; @@ -2875,8 +2926,9 @@ scf_operator_handler_t semantic_operator_handlers[] = { {{NULL, NULL}, SCF_LABEL, -1, -1, -1, _scf_op_semantic_label}, {{NULL, NULL}, SCF_OP_ERROR, -1, -1, -1, _scf_op_semantic_error}, - {{NULL, NULL}, SCF_OP_IF, -1, -1, -1, _scf_op_semantic_if}, - {{NULL, NULL}, SCF_OP_WHILE, -1, -1, -1, _scf_op_semantic_while}, + {{NULL, NULL}, SCF_OP_IF, -1, -1, -1, _scf_op_semantic_if}, + {{NULL, NULL}, SCF_OP_WHILE, -1, -1, -1, _scf_op_semantic_while}, + {{NULL, NULL}, SCF_OP_REPEAT, -1, -1, -1, _scf_op_semantic_repeat}, {{NULL, NULL}, SCF_OP_FOR, -1, -1, -1, _scf_op_semantic_for}, }; diff --git a/parse/scf_parse2.c b/parse/scf_parse.c similarity index 93% rename from parse/scf_parse2.c rename to parse/scf_parse.c index 8ba1577..15346ea 100644 --- a/parse/scf_parse2.c +++ b/parse/scf_parse.c @@ -41,155 +41,6 @@ scf_base_type_t base_types[] = { {SCF_FUNCTION_PTR, "funcptr", sizeof(void*)}, }; -extern scf_dfa_module_t dfa_module_include; - -extern scf_dfa_module_t dfa_module_identity; - -extern scf_dfa_module_t dfa_module_expr; -extern scf_dfa_module_t dfa_module_create; -extern scf_dfa_module_t dfa_module_call; -extern scf_dfa_module_t dfa_module_sizeof; -extern scf_dfa_module_t dfa_module_container; -extern scf_dfa_module_t dfa_module_init_data; -extern scf_dfa_module_t dfa_module_va_arg; - -extern scf_dfa_module_t dfa_module_union; -extern scf_dfa_module_t dfa_module_class; - -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_operator; - -extern scf_dfa_module_t dfa_module_if; -extern scf_dfa_module_t dfa_module_while; -extern scf_dfa_module_t dfa_module_for; - -#if 1 -extern scf_dfa_module_t dfa_module_break; -extern scf_dfa_module_t dfa_module_continue; -extern scf_dfa_module_t dfa_module_return; -extern scf_dfa_module_t dfa_module_goto; -extern scf_dfa_module_t dfa_module_label; -extern scf_dfa_module_t dfa_module_error; -extern scf_dfa_module_t dfa_module_async; -#endif -extern scf_dfa_module_t dfa_module_block; - -scf_dfa_module_t* dfa_modules[] = -{ - &dfa_module_include, - - &dfa_module_identity, - - &dfa_module_expr, - &dfa_module_create, - &dfa_module_call, - &dfa_module_sizeof, - &dfa_module_container, - &dfa_module_init_data, - &dfa_module_va_arg, - - &dfa_module_union, - &dfa_module_class, - - &dfa_module_type, - - &dfa_module_var, - - &dfa_module_function, - &dfa_module_operator, - - &dfa_module_if, - &dfa_module_while, - &dfa_module_for, - -#if 1 - &dfa_module_break, - &dfa_module_continue, - &dfa_module_goto, - &dfa_module_return, - &dfa_module_label, - &dfa_module_error, - &dfa_module_async, -#endif - &dfa_module_block, -}; - -#define SCF_CHECK_LEX_POP_WORD(w) \ - do {\ - int ret = scf_lex_pop_word(parse->lex, &w);\ - if (ret < 0) {\ - printf("%s(),%d, error: \n", __func__, __LINE__);\ - return -1;\ - }\ - } while (0) - - -int scf_parse_dfa_init(scf_parse_t* parse) -{ - if (scf_dfa_open(&parse->dfa, "parse", parse) < 0) { - scf_loge("\n"); - return -1; - } - - int nb_modules = sizeof(dfa_modules) / sizeof(dfa_modules[0]); - - parse->dfa_data = calloc(1, sizeof(dfa_parse_data_t)); - if (!parse->dfa_data) { - scf_loge("\n"); - return -1; - } - - parse->dfa_data->module_datas = calloc(nb_modules, sizeof(void*)); - if (!parse->dfa_data->module_datas) { - scf_loge("\n"); - return -1; - } - - parse->dfa_data->current_identities = scf_stack_alloc(); - if (!parse->dfa_data->current_identities) { - scf_loge("\n"); - return -1; - } - - int i; - for (i = 0; i < nb_modules; i++) { - - scf_dfa_module_t* m = dfa_modules[i]; - - if (!m) - continue; - - m->index = i; - - if (!m->init_module) - continue; - - if (m->init_module(parse->dfa) < 0) { - scf_loge("init module: %s\n", m->name); - return -1; - } - } - - for (i = 0; i < nb_modules; i++) { - - scf_dfa_module_t* m = dfa_modules[i]; - - if (!m || !m->init_syntax) - continue; - - if (m->init_syntax(parse->dfa) < 0) { - scf_loge("init syntax: %s\n", m->name); - return -1; - } - } - - return 0; -} - int scf_parse_open(scf_parse_t** pparse) { assert(pparse); @@ -1520,45 +1371,6 @@ static int _fill_function_inst(scf_string_t* code, scf_function_t* f, int64_t of return 0; } -static int _find_function(scf_node_t* node, void* arg, scf_vector_t* vec) -{ - if (SCF_FUNCTION == node->type) { - - scf_function_t* f = (scf_function_t*)node; - - return scf_vector_add(vec, f); - } - - return 0; -} - -static int _find_global_var(scf_node_t* node, void* arg, scf_vector_t* vec) -{ - if (SCF_OP_BLOCK == node->type - || (node->type >= SCF_STRUCT && node->class_flag)) { - - scf_block_t* b = (scf_block_t*)node; - - if (!b->scope || !b->scope->vars) - return 0; - - int i; - for (i = 0; i < b->scope->vars->size; i++) { - - scf_variable_t* v = b->scope->vars->data[i]; - - if (v->global_flag || v->static_flag) { - - int ret = scf_vector_add(vec, v); - if (ret < 0) - return ret; - } - } - } - - return 0; -} - static int _scf_parse_add_rela(scf_vector_t* relas, scf_parse_t* parse, scf_rela_t* r, const char* name, uint16_t st_shndx) { scf_elf_rela_t* rela; diff --git a/parse/scf_parse.h b/parse/scf_parse.h index c78dddb..c20bfa5 100644 --- a/parse/scf_parse.h +++ b/parse/scf_parse.h @@ -49,6 +49,7 @@ typedef struct { scf_lex_word_t* type_w; scf_type_t* type; + int number; int nb_pointers; scf_function_t* func_ptr; @@ -115,6 +116,8 @@ struct dfa_parse_data_s { int nb_rps; }; +int scf_parse_dfa_init(scf_parse_t* parse); + int scf_parse_open(scf_parse_t** pparse); int scf_parse_close(scf_parse_t* parse); @@ -122,5 +125,8 @@ int scf_parse_file(scf_parse_t* parse, const char* path); int scf_parse_compile(scf_parse_t* parse, const char* out, const char* arch); +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); + #endif diff --git a/parse/scf_parse_util.c b/parse/scf_parse_util.c index 377c822..afb059c 100644 --- a/parse/scf_parse_util.c +++ b/parse/scf_parse_util.c @@ -1,3 +1,41 @@ #include"scf_parse.h" +int _find_function(scf_node_t* node, void* arg, scf_vector_t* vec) +{ + if (SCF_FUNCTION == node->type) { + + scf_function_t* f = (scf_function_t*)node; + + return scf_vector_add(vec, f); + } + + return 0; +} + +int _find_global_var(scf_node_t* node, void* arg, scf_vector_t* vec) +{ + if (SCF_OP_BLOCK == node->type + || (node->type >= SCF_STRUCT && node->class_flag)) { + + scf_block_t* b = (scf_block_t*)node; + + if (!b->scope || !b->scope->vars) + return 0; + + int i; + for (i = 0; i < b->scope->vars->size; i++) { + + scf_variable_t* v = b->scope->vars->data[i]; + + if (v->global_flag || v->static_flag) { + + int ret = scf_vector_add(vec, v); + if (ret < 0) + return ret; + } + } + } + + return 0; +}