From f04c3c6561754d01b253a0eed24170a4725cdb14 Mon Sep 17 00:00:00 2001 From: "yu.dongliang" <18588496441@163.com> Date: Fri, 12 Apr 2024 20:08:30 +0800 Subject: [PATCH] support 'switch-case' & delete some unused code --- core/scf_3ac.c | 2 +- core/scf_3ac.h | 3 +- core/scf_core_types.h | 8 +- core/scf_lex_word.h | 1 - core/scf_operator.c | 7 +- core/scf_operator_handler.h | 12 +- core/scf_operator_handler_3ac.c | 769 ++++++++++++-------------- core/scf_optimizer_loop.c | 6 +- docs/Naja_float.txt | 122 ++++ docs/Naja_int.txt | 314 +++++++++++ examples/switch_case.c | 19 + lex/scf_lex.c | 1 - parse/Makefile | 5 +- parse/scf_dfa.c | 2 +- parse/scf_dfa_block.c | 26 +- parse/scf_dfa_class.c | 47 +- parse/scf_dfa_do.c | 226 ++++++++ parse/scf_dfa_error.c | 175 ------ parse/scf_dfa_for.c | 15 +- parse/scf_dfa_function.c | 6 +- parse/scf_dfa_goto.c | 9 +- parse/scf_dfa_if.c | 49 +- parse/scf_dfa_include.c | 9 +- parse/scf_dfa_label.c | 11 +- parse/scf_dfa_operator.c | 6 +- parse/scf_dfa_parse.c | 8 +- parse/scf_dfa_repeat.c | 232 -------- parse/scf_dfa_return.c | 9 +- parse/scf_dfa_struct.c | 545 ------------------ parse/scf_dfa_switch.c | 285 ++++++++++ parse/scf_dfa_util.h | 28 + parse/scf_dfa_var.c | 9 +- parse/scf_dfa_while.c | 16 +- parse/scf_operator_handler_const.c | 245 ++++---- parse/scf_operator_handler_expr.c | 54 +- parse/scf_operator_handler_semantic.c | 360 ++++++------ parse/scf_parse.c | 2 + parse/scf_rbtree.c | 713 ------------------------ 38 files changed, 1751 insertions(+), 2605 deletions(-) create mode 100644 docs/Naja_float.txt create mode 100644 docs/Naja_int.txt create mode 100644 examples/switch_case.c create mode 100644 parse/scf_dfa_do.c delete mode 100644 parse/scf_dfa_error.c delete mode 100644 parse/scf_dfa_repeat.c delete mode 100644 parse/scf_dfa_struct.c create mode 100644 parse/scf_dfa_switch.c delete mode 100644 parse/scf_rbtree.c diff --git a/core/scf_3ac.c b/core/scf_3ac.c index e15270c..f7f993f 100644 --- a/core/scf_3ac.c +++ b/core/scf_3ac.c @@ -414,7 +414,7 @@ scf_3ac_code_t* scf_3ac_alloc_by_dst(int op_type, scf_dag_node_t* dst) return c; } -scf_3ac_code_t* scf_branch_ops_code(int type, scf_label_t* l, scf_node_t* err) +scf_3ac_code_t* scf_3ac_jmp_code(int type, scf_label_t* l, scf_node_t* err) { scf_3ac_operand_t* dst; scf_3ac_code_t* c; diff --git a/core/scf_3ac.h b/core/scf_3ac.h index a1c0b09..406eacc 100644 --- a/core/scf_3ac.h +++ b/core/scf_3ac.h @@ -61,7 +61,7 @@ void scf_3ac_code_print(scf_3ac_code_t* c, scf_list_t* sentinel); void scf_3ac_list_print(scf_list_t* h); -scf_3ac_code_t* scf_branch_ops_code(int type, scf_label_t* l, scf_node_t* err); +scf_3ac_code_t* scf_3ac_jmp_code(int type, scf_label_t* l, scf_node_t* err); scf_3ac_operator_t* scf_3ac_find_operator(const int type); @@ -76,4 +76,3 @@ int scf_3ac_split_basic_blocks(scf_list_t* list_head_3ac, scf_function_t* f) int scf_3ac_code_same(scf_3ac_code_t* c0, scf_3ac_code_t* c1); #endif - diff --git a/core/scf_core_types.h b/core/scf_core_types.h index 100bbc6..7326090 100644 --- a/core/scf_core_types.h +++ b/core/scf_core_types.h @@ -104,12 +104,16 @@ 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_DO, // do statement + + SCF_OP_SWITCH, // switch-case statement + SCF_OP_CASE, + SCF_OP_DEFAULT, + SCF_OP_RETURN, // return statement SCF_OP_BREAK, // break statement SCF_OP_CONTINUE, // continue statement SCF_OP_ASYNC, // async statement - SCF_OP_ERROR, // error statement SCF_OP_INCLUDE, // include statement // 58 diff --git a/core/scf_lex_word.h b/core/scf_lex_word.h index c25212b..44061f7 100644 --- a/core/scf_lex_word.h +++ b/core/scf_lex_word.h @@ -102,7 +102,6 @@ enum scf_lex_words { SCF_LEX_WORD_KEY_RETURN, // return SCF_LEX_WORD_KEY_GOTO, // goto - SCF_LEX_WORD_KEY_ERROR, // error SCF_LEX_WORD_KEY_SIZEOF, // sizeof diff --git a/core/scf_operator.c b/core/scf_operator.c index 68412dc..f94eb87 100644 --- a/core/scf_operator.c +++ b/core/scf_operator.c @@ -70,12 +70,15 @@ static scf_operator_t base_operators[] = { {SCF_OP_CONTINUE, "continue", 15, -1, SCF_OP_ASSOCIATIVITY_LEFT}, {SCF_OP_GOTO, "goto", 15, -1, SCF_OP_ASSOCIATIVITY_LEFT}, {SCF_LABEL, "label", 15, -1, SCF_OP_ASSOCIATIVITY_LEFT}, - {SCF_OP_ERROR, "error", 15, -1, SCF_OP_ASSOCIATIVITY_LEFT}, {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_DO, "do", 15, -1, SCF_OP_ASSOCIATIVITY_LEFT}, {SCF_OP_FOR, "for", 15, -1, SCF_OP_ASSOCIATIVITY_LEFT}, + + {SCF_OP_SWITCH, "switch", 15, -1, SCF_OP_ASSOCIATIVITY_LEFT}, + {SCF_OP_CASE, "case", 15, -1, SCF_OP_ASSOCIATIVITY_LEFT}, + {SCF_OP_DEFAULT, "default", 15, -1, SCF_OP_ASSOCIATIVITY_LEFT}, }; scf_operator_t* scf_find_base_operator(const char* name, const int nb_operands) diff --git a/core/scf_operator_handler.h b/core/scf_operator_handler.h index acca510..a545e41 100644 --- a/core/scf_operator_handler.h +++ b/core/scf_operator_handler.h @@ -7,22 +7,14 @@ typedef struct scf_operator_handler_s scf_operator_handler_t; typedef int (*scf_operator_handler_pt)(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* data); -struct scf_operator_handler_s { - - scf_list_t list; - +struct scf_operator_handler_s +{ int type; - scf_operator_handler_pt func; }; -scf_operator_handler_t* scf_operator_handler_alloc(int type, scf_operator_handler_pt func); - -void scf_operator_handler_free(scf_operator_handler_t* h); - scf_operator_handler_t* scf_find_3ac_operator_handler(const int type); int scf_function_to_3ac(scf_ast_t* ast, scf_function_t* f, scf_list_t* _3ac_list_head); #endif - diff --git a/core/scf_operator_handler_3ac.c b/core/scf_operator_handler_3ac.c index bcc4c7d..822265f 100644 --- a/core/scf_operator_handler_3ac.c +++ b/core/scf_operator_handler_3ac.c @@ -7,7 +7,6 @@ typedef struct { scf_vector_t* _continues; scf_vector_t* _gotos; scf_vector_t* _labels; - scf_vector_t* _errors; scf_vector_t* _ends; } scf_branch_ops_t; @@ -20,14 +19,14 @@ typedef struct { scf_branch_ops_t* scf_branch_ops_alloc() { scf_branch_ops_t* branch_ops = calloc(1, sizeof(scf_branch_ops_t)); - assert(branch_ops); - branch_ops->_breaks = scf_vector_alloc(); - branch_ops->_continues = scf_vector_alloc(); - branch_ops->_gotos = scf_vector_alloc(); - branch_ops->_labels = scf_vector_alloc(); - branch_ops->_errors = scf_vector_alloc(); - branch_ops->_ends = scf_vector_alloc(); + if (branch_ops) { + branch_ops->_breaks = scf_vector_alloc(); + branch_ops->_continues = scf_vector_alloc(); + branch_ops->_gotos = scf_vector_alloc(); + branch_ops->_labels = scf_vector_alloc(); + branch_ops->_ends = scf_vector_alloc(); + } return branch_ops; } @@ -39,7 +38,6 @@ void scf_branch_ops_free(scf_branch_ops_t* branch_ops) scf_vector_free(branch_ops->_continues); scf_vector_free(branch_ops->_gotos); scf_vector_free(branch_ops->_labels); - scf_vector_free(branch_ops->_errors); scf_vector_free(branch_ops->_ends); free(branch_ops); @@ -49,20 +47,19 @@ void scf_branch_ops_free(scf_branch_ops_t* branch_ops) static int _scf_expr_calculate_internal(scf_ast_t* ast, scf_node_t* node, void* data) { - if (!node) { + if (!node) return 0; - } - scf_handler_data_t* d = data; + scf_handler_data_t* d = data; + scf_operator_handler_t* h; + + int i; if (0 == node->nb_nodes) { - if (scf_type_is_var(node->type) && node->var->w) { + if (scf_type_is_var(node->type) && node->var->w) scf_logd("node->var->w->text->data: %s\n", node->var->w->text->data); - } - assert(scf_type_is_var(node->type) - || SCF_LABEL == node->type - || node->split_flag); + assert(scf_type_is_var(node->type) || SCF_LABEL == node->type || node->split_flag); return 0; } @@ -78,15 +75,10 @@ static int _scf_expr_calculate_internal(scf_ast_t* ast, scf_node_t* node, void* return 0; node->_3ac_done = 1; - if (node->w) - scf_logd("node: %p, node->w->text->data: %s\n", node, node->w->text->data); - if (SCF_OP_ASSOCIATIVITY_LEFT == node->op->associativity) { - // left associativity - scf_logd("left associativity\n"); if (SCF_OP_LOGIC_AND != node->op->type && SCF_OP_LOGIC_OR != node->op->type) { - int i; + for (i = 0; i < node->nb_nodes; i++) { if (_scf_expr_calculate_internal(ast, node->nodes[i], d) < 0) { scf_loge("\n"); @@ -95,26 +87,17 @@ static int _scf_expr_calculate_internal(scf_ast_t* ast, scf_node_t* node, void* } } - scf_operator_handler_t* h = scf_find_3ac_operator_handler(node->op->type); + h = scf_find_3ac_operator_handler(node->op->type); if (!h) { scf_loge("\n"); return -1; } - int ret = h->func(ast, node->nodes, node->nb_nodes, d); + return h->func(ast, node->nodes, node->nb_nodes, d); - if (ret < 0) { - scf_loge("\n"); - return -1; - } - return 0; } else { - // right associativity - scf_logd("right associativity\n"); + 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) { - int i; for (i = node->nb_nodes - 1; i >= 0; i--) { if (_scf_expr_calculate_internal(ast, node->nodes[i], d) < 0) { scf_loge("\n"); @@ -123,19 +106,13 @@ static int _scf_expr_calculate_internal(scf_ast_t* ast, scf_node_t* node, void* } } - scf_operator_handler_t* h = scf_find_3ac_operator_handler(node->op->type); + h = scf_find_3ac_operator_handler(node->op->type); if (!h) { scf_loge("op->type: %d, name: '%s'\n", node->op->type, node->op->name); return -1; } - int ret = h->func(ast, node->nodes, node->nb_nodes, d); - - if (ret < 0) { - scf_loge("\n"); - return -1; - } - return 0; + return h->func(ast, node->nodes, node->nb_nodes, d); } scf_loge("\n"); @@ -151,9 +128,8 @@ static int _scf_expr_calculate(scf_ast_t* ast, scf_expr_t* e, void* data) scf_node_t* root = e->nodes[0]; - if (scf_type_is_var(root->type)) { + if (scf_type_is_var(root->type)) return 0; - } if (_scf_expr_calculate_internal(ast, root, d) < 0) { scf_loge("\n"); @@ -395,29 +371,25 @@ static int _scf_op_block(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* if (0 == nb_nodes) return 0; - scf_handler_data_t* d = data; - - scf_block_t* b = (scf_block_t*)(nodes[0]->parent); + scf_operator_handler_t* h; + scf_operator_t* op; + scf_handler_data_t* d = data; + scf_block_t* b = (scf_block_t*)(nodes[0]->parent); + scf_block_t* up = ast->current_block; + scf_node_t* node; if (b->node._3ac_done) return 0; - scf_block_t* prev_block = ast->current_block; ast->current_block = b; - int i = 0; - while (i < nb_nodes) { - scf_node_t* node = nodes[i]; - scf_operator_t* op = node->op; - scf_logd("node: %p, type: %d, i: %d, nb_nodes: %d\n", node, node->type, i, nb_nodes); + int i; + int j; - if (SCF_LABEL == node->type) { - scf_logd("node: %p, w: %s, line:%d\n", node, node->label->w->text->data, node->label->w->line); - } else if (scf_type_is_var(node->type)) { - scf_logd("node: %p, w: %s, line:%d\n", node, node->var->w->text->data, node->var->w->line); - } else if (node->w) { - scf_logd("node: %p, w: %s, line:%d\n", node, node->w->text->data, node->w->line); - } + for (i = 0; i < nb_nodes; i++) { + + node = nodes[i]; + op = node->op; if (!op) { op = scf_find_base_operator_by_type(node->type); @@ -427,7 +399,7 @@ static int _scf_op_block(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* } } - scf_operator_handler_t* h = scf_find_3ac_operator_handler(op->type); + h = scf_find_3ac_operator_handler(op->type); if (!h) { scf_loge("\n"); return -1; @@ -435,16 +407,18 @@ static int _scf_op_block(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* if (h->func(ast, node->nodes, node->nb_nodes, d) < 0) { scf_loge("\n"); - ast->current_block = prev_block; + ast->current_block = up; return -1; } // for goto if (SCF_LABEL == node->type) { - scf_label_t* l = node->label; - scf_list_t* tail = scf_list_tail(d->_3ac_list_head); - scf_3ac_code_t* end = scf_list_data(tail, scf_3ac_code_t, list); + scf_label_t* l = node->label; + scf_list_t* tail = scf_list_tail(d->_3ac_list_head); + scf_3ac_code_t* end = scf_list_data(tail, scf_3ac_code_t, list); + scf_3ac_code_t* c; + scf_3ac_operand_t* dst; if (scf_vector_add(d->branch_ops->_labels, end) < 0) { scf_loge("\n"); @@ -454,28 +428,23 @@ static int _scf_op_block(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* int j; for (j = 0; j < d->branch_ops->_gotos->size; j++) { + c = d->branch_ops->_gotos->data[j]; - scf_3ac_code_t* c = d->branch_ops->_gotos->data[j]; if (!c) continue; assert(l->w); assert(c->label->w); - scf_logi("l: %s, c->label: %s\n", l->w->text->data, c->label->w->text->data); - if (!strcmp(l->w->text->data, c->label->w->text->data)) { - scf_logi("j: %d\n", j); - scf_3ac_operand_t* dst = c->dsts->data[0]; + dst = c->dsts->data[0]; dst->code = end; } } } - - i++; } - ast->current_block = prev_block; + ast->current_block = up; return 0; } @@ -518,7 +487,7 @@ static int _scf_op_return(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void return -1; } - scf_3ac_code_t* end = scf_branch_ops_code(SCF_OP_GOTO, NULL, NULL); + scf_3ac_code_t* end = scf_3ac_jmp_code(SCF_OP_GOTO, NULL, NULL); scf_list_add_tail(d->_3ac_list_head, &end->list); @@ -527,56 +496,51 @@ static int _scf_op_return(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void static int _scf_op_break(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* data) { - scf_handler_data_t* d = data; - - scf_node_t* n = (scf_node_t*)ast->current_block; + scf_handler_data_t* d = data; + scf_node_t* up = (scf_node_t*)ast->current_block; - while (n - && SCF_OP_WHILE != n->type - && SCF_OP_REPEAT != n->type - && SCF_OP_FOR != n->type) - n = n->parent; + while (up + && SCF_OP_WHILE != up->type + && SCF_OP_DO != up->type + && SCF_OP_FOR != up->type + && SCF_OP_SWITCH != up->type) + up = up->parent; - if (!n) { + if (!up) { scf_loge("\n"); return -1; } - assert(SCF_OP_WHILE == n->type || SCF_OP_FOR == n->type || SCF_OP_REPEAT == n->type); - scf_node_t* parent = n->parent; - assert(parent); + scf_3ac_code_t* jmp = scf_3ac_jmp_code(SCF_OP_GOTO, NULL, NULL); - scf_3ac_code_t* branch = scf_branch_ops_code(SCF_OP_GOTO, NULL, NULL); - - scf_list_add_tail(d->_3ac_list_head, &branch->list); + scf_list_add_tail(d->_3ac_list_head, &jmp->list); - scf_vector_add(d->branch_ops->_breaks, branch); + scf_vector_add(d->branch_ops->_breaks, jmp); return 0; } static int _scf_op_continue(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* data) { - scf_handler_data_t* d = data; - - scf_node_t* n = (scf_node_t*)ast->current_block; + scf_handler_data_t* d = data; + scf_node_t* up = (scf_node_t*)ast->current_block; - while (n - && SCF_OP_WHILE != n->type - && SCF_OP_REPEAT != n->type - && SCF_OP_FOR != n->type) - n = n->parent; + while (up + && SCF_OP_WHILE != up->type + && SCF_OP_DO != up->type + && SCF_OP_FOR != up->type + && SCF_OP_SWITCH != up->type) + up = up->parent; - if (!n) { + if (!up) { scf_loge("\n"); return -1; } - assert(SCF_OP_WHILE == n->type || SCF_OP_FOR == n->type || SCF_OP_REPEAT == n->type); - scf_3ac_code_t* branch = scf_branch_ops_code(SCF_OP_GOTO, NULL, NULL); + scf_3ac_code_t* jmp = scf_3ac_jmp_code(SCF_OP_GOTO, NULL, NULL); - scf_list_add_tail(d->_3ac_list_head, &branch->list); + scf_list_add_tail(d->_3ac_list_head, &jmp->list); - scf_vector_add(d->branch_ops->_continues, branch); + scf_vector_add(d->branch_ops->_continues, jmp); return 0; } @@ -589,95 +553,31 @@ static int _scf_op_goto(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* { assert(1 == nb_nodes); - scf_handler_data_t* d = data; + scf_handler_data_t* d = data; + scf_node_t* nl = nodes[0]; + scf_label_t* l = nl->label; - scf_node_t* nl = nodes[0]; assert(SCF_LABEL == nl->type); - - scf_label_t* l = nl->label; assert(l->w); scf_3ac_operand_t* dst; - scf_3ac_code_t* branch = scf_branch_ops_code(SCF_OP_GOTO, l, NULL); - scf_list_add_tail(d->_3ac_list_head, &branch->list); + scf_3ac_code_t* c; + scf_3ac_code_t* jmp = scf_3ac_jmp_code(SCF_OP_GOTO, l, NULL); + + scf_list_add_tail(d->_3ac_list_head, &jmp->list); int i; for (i = 0; i < d->branch_ops->_labels->size; i++) { - scf_3ac_code_t* c = d->branch_ops->_labels->data[i]; + c = d->branch_ops->_labels->data[i]; if (!strcmp(l->w->text->data, c->label->w->text->data)) { - dst = branch->dsts->data[0]; + dst = jmp->dsts->data[0]; dst->code = c; break; } } - scf_vector_add(d->branch_ops->_gotos, branch); - return 0; -} - -static int _scf_op_error(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* data) -{ - assert(nb_nodes >= 3); - - scf_handler_data_t* d = data; - - scf_expr_t* e = nodes[0]; - scf_node_t* parent = e->parent; - int ret; - int i; - - if (_scf_expr_calculate(ast, e, d) < 0) { - scf_loge("\n"); - return -1; - } - - if (_scf_3ac_code_1(d->_3ac_list_head, SCF_OP_3AC_TEQ, e->nodes[0]) < 0) { - scf_loge("\n"); - return -1; - } - - scf_3ac_operand_t* dst; - scf_3ac_code_t* je = scf_branch_ops_code(SCF_OP_3AC_JZ, NULL, parent); - scf_3ac_code_t* jmp = scf_branch_ops_code(SCF_OP_GOTO, NULL, parent); - scf_list_add_tail(d->_3ac_list_head, &je->list); - - // print log if needs - if (nb_nodes > 3) { - scf_vector_t* argv = scf_vector_alloc(); - - for (i = 3; i < nb_nodes; i++) { - - e = nodes[i]; - ret = _scf_expr_calculate(ast, e, d); - SCF_CHECK_ERROR(ret < 0, ret, "expr calculate failed\n"); - - scf_vector_add(argv, e->nodes[0]); - } - - //ret = _scf_3ac_call_extern(d->_3ac_list_head, "printf", parent, (scf_node_t**)argv->data, argv->size); - scf_vector_free(argv); - argv = NULL; - SCF_CHECK_ERROR(ret < 0, ret, "expr calculate failed\n"); - } - - // calculate error code to return - e = nodes[2]; - ret = _scf_expr_calculate(ast, e, d); - SCF_CHECK_ERROR(ret < 0, ret, "expr calculate failed\n"); - - // push error code to stack, and we will pop & return it when exit this function - _scf_3ac_code_1(d->_3ac_list_head, SCF_OP_3AC_PUSH, e->nodes[0]); - - // set the 'je' destination (code when no error happens) - dst = je->dsts->data[0]; - dst->code = jmp; - - // add 'jmp' to code list & error branches, it will be re-filled when this function end - scf_list_add_tail(d->_3ac_list_head, &jmp->list); - scf_vector_add(d->branch_ops->_errors, jmp); - scf_vector_add(d->branch_ops->_errors, je); // 'je' will re-fill too. - + scf_vector_add(d->branch_ops->_gotos, jmp); return 0; } @@ -836,7 +736,7 @@ static int _scf_op_if(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* da } scf_3ac_operand_t* dst; - scf_3ac_code_t* jmp_else = scf_branch_ops_code(jmp_op, NULL, NULL); + scf_3ac_code_t* jmp_else = scf_3ac_jmp_code(jmp_op, NULL, NULL); scf_3ac_code_t* jmp_endif = NULL; scf_list_t* l; @@ -853,7 +753,7 @@ static int _scf_op_if(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* da if (1 == i) { if (3 == nb_nodes) { - jmp_endif = scf_branch_ops_code(SCF_OP_GOTO, NULL, NULL); + jmp_endif = scf_3ac_jmp_code(SCF_OP_GOTO, NULL, NULL); scf_list_add_tail(d->_3ac_list_head, &jmp_endif->list); } @@ -890,15 +790,18 @@ static int _scf_op_end_loop(scf_list_t* start_prev, scf_list_t* continue_prev, s // for optimizer // copy cond expr - scf_list_t* l; - scf_list_t* l2; - scf_list_t* cond_prev = scf_list_tail(d->_3ac_list_head); + scf_3ac_operand_t* dst; + scf_3ac_code_t* c; + scf_3ac_code_t* c2; - for (l = scf_list_next(start_prev); l != &jmp_end->list; l = scf_list_next(l)) { + scf_list_t* l; + scf_list_t* l2; + scf_list_t* cond_prev = scf_list_tail(d->_3ac_list_head); - scf_3ac_code_t* c = scf_list_data(l, scf_3ac_code_t, list); + for (l = scf_list_next(start_prev); l != &jmp_end->list; l = scf_list_next(l)) { + c = scf_list_data(l, scf_3ac_code_t, list); - scf_3ac_code_t* c2 = scf_3ac_code_clone(c); + c2 = scf_3ac_code_clone(c); if (!c2) return -ENOMEM; @@ -906,16 +809,15 @@ static int _scf_op_end_loop(scf_list_t* start_prev, scf_list_t* continue_prev, s } for (l = scf_list_next(cond_prev); l != scf_list_sentinel(d->_3ac_list_head); l = scf_list_next(l)) { - - scf_3ac_code_t* c = scf_list_data(l, scf_3ac_code_t, list); + c = scf_list_data(l, scf_3ac_code_t, list); if (!scf_type_is_jmp(c->op->type)) continue; for (l2 = scf_list_next(cond_prev); l2 != scf_list_sentinel(d->_3ac_list_head); l2 = scf_list_next(l2)) { + c2 = scf_list_data(l2, scf_3ac_code_t, list); - scf_3ac_code_t* c2 = scf_list_data(l2, scf_3ac_code_t, list); - scf_3ac_operand_t* dst = c->dsts->data[0]; + dst = c->dsts->data[0]; if (dst->code == c2->origin) { dst->code = c2; @@ -970,25 +872,25 @@ static int _scf_op_end_loop(scf_list_t* start_prev, scf_list_t* continue_prev, s }; // add loop when true - scf_3ac_code_t* loop = scf_branch_ops_code(jmp_op, NULL, NULL); + scf_3ac_code_t* loop = scf_3ac_jmp_code(jmp_op, NULL, NULL); scf_list_add_tail(d->_3ac_list_head, &loop->list); // should get the real start here, - scf_3ac_code_t* start = scf_list_data(scf_list_next(&jmp_end->list), scf_3ac_code_t, list); - scf_3ac_operand_t* dst = loop->dsts->data[0]; + scf_3ac_code_t* start = scf_list_data(scf_list_next(&jmp_end->list), scf_3ac_code_t, list); + + dst = loop->dsts->data[0]; dst->code = start; // set jmp destination for 'continue', // it's the 'real' dst & needs not to re-fill - scf_3ac_code_t* branch = NULL; int i; for (i = 0; i < d->branch_ops->_continues->size; i++) { - branch = d->branch_ops->_continues->data[i]; + c = d->branch_ops->_continues->data[i]; - assert(branch->dsts); + assert(c->dsts); - dst = branch->dsts->data[0]; + dst = c->dsts->data[0]; assert(!dst->code); /* 'continue' will goto 'while' and re-check the condition. @@ -1012,11 +914,11 @@ static int _scf_op_end_loop(scf_list_t* start_prev, scf_list_t* continue_prev, s scf_3ac_code_t* end_prev = scf_list_data(scf_list_tail(d->_3ac_list_head), scf_3ac_code_t, list); for (i = 0; i < d->branch_ops->_breaks->size; i++) { - branch = d->branch_ops->_breaks->data[i]; + c = d->branch_ops->_breaks->data[i]; - assert(branch->dsts); + assert(c->dsts); - dst = branch->dsts->data[0]; + dst = c->dsts->data[0]; if (!dst->code) dst->code = end_prev; @@ -1029,10 +931,9 @@ static int _scf_op_end_loop(scf_list_t* start_prev, scf_list_t* continue_prev, s if (up_branch_ops) { for (i = 0; i < d->branch_ops->_breaks->size; i++) { - branch = d->branch_ops->_breaks->data[i]; - assert(branch); + c = d->branch_ops->_breaks->data[i]; - if (scf_vector_add(up_branch_ops->_breaks, branch) < 0) + if (scf_vector_add(up_branch_ops->_breaks, c) < 0) return -1; } @@ -1042,26 +943,16 @@ static int _scf_op_end_loop(scf_list_t* start_prev, scf_list_t* continue_prev, s } for (i = 0; i < d->branch_ops->_gotos->size; i++) { - branch = d->branch_ops->_gotos->data[i]; - assert(branch); + c = d->branch_ops->_gotos->data[i]; - if (scf_vector_add(up_branch_ops->_gotos, branch) < 0) - return -1; - } - - for (i = 0; i < d->branch_ops->_errors->size; i++) { - branch = d->branch_ops->_errors->data[i]; - assert(branch); - - if (scf_vector_add(up_branch_ops->_errors, branch) < 0) + if (scf_vector_add(up_branch_ops->_gotos, c) < 0) return -1; } for (i = 0; i < d->branch_ops->_ends->size; i++) { - branch = d->branch_ops->_ends->data[i]; - assert(branch); + c = d->branch_ops->_ends->data[i]; - if (scf_vector_add(up_branch_ops->_ends, branch) < 0) + if (scf_vector_add(up_branch_ops->_ends, c) < 0) return -1; } } @@ -1069,7 +960,7 @@ 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) +static int _scf_op_do(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* data) { assert(2 == nb_nodes); @@ -1088,7 +979,7 @@ static int _scf_op_repeat(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void scf_list_t* l; scf_3ac_code_t* c; - scf_3ac_code_t* jmp_end = scf_branch_ops_code(jmp_op, NULL, NULL); + scf_3ac_code_t* jmp_end = scf_3ac_jmp_code(jmp_op, NULL, NULL); scf_list_add_tail(d->_3ac_list_head, &jmp_end->list); @@ -1134,8 +1025,8 @@ static int _scf_op_while(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* assert(2 == nb_nodes || 1 == nb_nodes); scf_handler_data_t* d = data; + scf_expr_t* e = nodes[0]; - scf_expr_t* e = nodes[0]; assert(SCF_OP_EXPR == e->type); // we don't know the real start of the while loop here, @@ -1148,7 +1039,7 @@ static int _scf_op_while(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* return -1; } - scf_3ac_code_t* jmp_end = scf_branch_ops_code(jmp_op, NULL, NULL); + scf_3ac_code_t* jmp_end = scf_3ac_jmp_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(); @@ -1174,6 +1065,141 @@ static int _scf_op_while(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* return 0; } +static int _scf_op_default(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* data) +{ + return 0; +} + +static int _scf_op_case(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* data) +{ + return 0; +} + +static int _scf_op_switch(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[0]; + scf_node_t* b = nodes[1]; + + assert(SCF_OP_EXPR == e->type); + + while (e && SCF_OP_EXPR == e->type) + e = e->nodes[0]; + + if (_scf_expr_calculate_internal(ast, e, d) < 0) { + scf_loge("\n"); + return -1; + } + + scf_branch_ops_t* up_branch_ops = d->branch_ops; + scf_block_t* up = ast->current_block; + + d->branch_ops = scf_branch_ops_alloc(); + ast->current_block = (scf_block_t*)b; + + scf_3ac_operand_t* dst; + scf_3ac_code_t* cmp; + scf_3ac_code_t* end; + scf_3ac_code_t* c; + scf_3ac_code_t* jnot = NULL; + scf_3ac_code_t* jnext = NULL; + + scf_node_t* child; + scf_expr_t* e2; + scf_list_t* l; + + int i; + for (i = 0; i < b->nb_nodes; i++) { + child = b->nodes[i]; + + if (SCF_OP_CASE == child->type || SCF_OP_DEFAULT == child->type) { + + if (jnot) { + jnext = scf_3ac_jmp_code(SCF_OP_GOTO, NULL, NULL); + + scf_list_add_tail(d->_3ac_list_head, &jnext->list); + scf_vector_add(up_branch_ops->_breaks, jnext); + + dst = jnot->dsts->data[0]; + dst->code = jnext; + jnot = NULL; + } + + if (SCF_OP_CASE == child->type) { + + e2 = child->nodes[0]; + assert(SCF_OP_EXPR == e2->type); + + while (e2 && SCF_OP_EXPR == e2->type) + e2 = e2->nodes[0]; + + if (_scf_expr_calculate_internal(ast, e2, d) < 0) { + scf_loge("\n"); + return -1; + } + + scf_node_t* srcs[2] = {e, e2}; + + cmp = scf_3ac_code_NN(SCF_OP_3AC_CMP, NULL, 0, srcs, 2); + jnot = scf_3ac_jmp_code(SCF_OP_3AC_JNZ, NULL, NULL); + + scf_list_add_tail(d->_3ac_list_head, &cmp->list); + scf_list_add_tail(d->_3ac_list_head, &jnot->list); + + scf_vector_add(up_branch_ops->_breaks, jnot); + } + + if (jnext) { + l = scf_list_tail(d->_3ac_list_head); + dst = jnext->dsts->data[0]; + dst->code = scf_list_data(l, scf_3ac_code_t, list); + jnext = NULL; + } + + } else { + if (_scf_op_node(ast, child, d) < 0) { + scf_loge("\n"); + return -1; + } + } + } + + l = scf_list_tail(d->_3ac_list_head); + end = scf_list_data(l, scf_3ac_code_t, list); + + for (i = 0; i < d->branch_ops->_breaks->size; i++) { + c = d->branch_ops->_breaks->data[i]; + + dst = c->dsts->data[0]; + if (!dst->code) + dst->code = end; + + if (scf_vector_add(up_branch_ops->_breaks, c) < 0) + return -1; + } + + for (i = 0; i < d->branch_ops->_gotos->size; i++) { + c = d->branch_ops->_gotos->data[i]; + + if (scf_vector_add(up_branch_ops->_gotos, c) < 0) + return -1; + } + + for (i = 0; i < d->branch_ops->_ends->size; i++) { + c = d->branch_ops->_ends->data[i]; + + if (scf_vector_add(up_branch_ops->_ends, c) < 0) + return -1; + } + + scf_branch_ops_free(d->branch_ops); + d->branch_ops = up_branch_ops; + ast->current_block = up; + return 0; +} + static int _scf_op_for(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* data) { assert(4 == nb_nodes); @@ -1199,7 +1225,7 @@ static int _scf_op_for(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* d return -1; } - jmp_end = scf_branch_ops_code(jmp_op, NULL, NULL); + jmp_end = scf_3ac_jmp_code(jmp_op, NULL, NULL); scf_list_add_tail(d->_3ac_list_head, &jmp_end->list); } @@ -1234,81 +1260,38 @@ static int _scf_op_for(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* d return 0; } -static int _scf_do_error(scf_ast_t* ast, scf_node_t* err, scf_handler_data_t* d) -{ - assert(err->nb_nodes >= 3); - - scf_expr_t* e = err->nodes[1]; - - int i; - int ret = _scf_expr_calculate(ast, e, d); - SCF_CHECK_ERROR(ret < 0, ret, "expr calculate failed\n"); - - scf_variable_t* r = e->result; - assert(r); - - scf_function_t* f = NULL; - scf_type_t* t = NULL; - - if (r->type >= SCF_STRUCT && 1 == r->nb_pointers) { - - ret = scf_ast_find_type_type(&t, ast, r->type); - assert(0 == ret); - assert(t); - - f = scf_scope_find_function(t->scope, "release"); - scf_logw("type '%s' has no release() function, use default\n", t->name->data); - } - - scf_vector_t* argv = scf_vector_alloc(); - scf_vector_add(argv, f); - scf_vector_add(argv, e->nodes[0]); - -// ret = _scf_3ac_call_extern(d->_3ac_list_head, "scf_delete", NULL, (scf_node_t**)argv->data, argv->size); - scf_vector_free(argv); - argv = NULL; - SCF_CHECK_ERROR(ret < 0, ret, "call scf_delete failed\n"); - - return 0; -} - static int __scf_op_call(scf_ast_t* ast, scf_function_t* f, void* data) { scf_logd("f: %p, f->node->w: %s\n", f, f->node.w->text->data); scf_handler_data_t* d = data; - // save & change the current block - scf_block_t* prev_block = ast->current_block; - ast->current_block = (scf_block_t*)f; + scf_block_t* up = ast->current_block; + scf_branch_ops_t* local_branch_ops = scf_branch_ops_alloc(); + scf_branch_ops_t* tmp_branch_ops = d->branch_ops; - scf_branch_ops_t* local_branch_ops = scf_branch_ops_alloc(); - scf_branch_ops_t* tmp_branch_ops = d->branch_ops; - d->branch_ops = local_branch_ops; + ast->current_block = (scf_block_t*)f; + d->branch_ops = local_branch_ops; // use local_branch_ops, because branch code should NOT jmp over the function block - // use local_branch_ops, because branch code should NOT jmp over the function block if (_scf_op_block(ast, f->node.nodes, f->node.nb_nodes, d) < 0) { scf_loge("\n"); return -1; } - if (_scf_3ac_code_1(d->_3ac_list_head, SCF_OP_3AC_END, NULL) < 0) { - scf_loge("\n"); - return -1; - } + scf_list_t* next; + scf_3ac_operand_t* dst; + scf_3ac_code_t* c; + scf_3ac_code_t* end = scf_3ac_code_NN(SCF_OP_3AC_END, NULL, 0, NULL, 0); - scf_3ac_code_t* err; - scf_node_t* node; - scf_list_t* tail; - scf_list_t* next; - int i; - int ret; + scf_list_add_tail(d->_3ac_list_head, &end->list); // re-fill 'break' + + int i; for (i = 0; i < local_branch_ops->_breaks->size; i++) { + c = local_branch_ops->_breaks->data[i]; - scf_3ac_code_t* c = local_branch_ops->_breaks->data[i]; - scf_3ac_operand_t* dst = c->dsts->data[0]; + dst = c->dsts->data[0]; if (dst->code) { next = scf_list_next(&dst->code->list); @@ -1321,9 +1304,9 @@ static int __scf_op_call(scf_ast_t* ast, scf_function_t* f, void* data) // re-fill 'goto' for (i = 0; i < local_branch_ops->_gotos->size; i++) { + c = local_branch_ops->_gotos->data[i]; - scf_3ac_code_t* c = local_branch_ops->_gotos->data[i]; - scf_3ac_operand_t* dst = c->dsts->data[0]; + dst = c->dsts->data[0]; if (dst->code) { next = scf_list_next(&dst->code->list); @@ -1336,76 +1319,23 @@ static int __scf_op_call(scf_ast_t* ast, scf_function_t* f, void* data) // re-fill 'end' for (i = 0; i < local_branch_ops->_ends->size; i++) { + c = local_branch_ops->_ends->data[i]; - scf_3ac_code_t* c = local_branch_ops->_ends->data[i]; - scf_list_t* l = scf_list_tail(d->_3ac_list_head); - scf_3ac_code_t* end = scf_list_data(l, scf_3ac_code_t, list); - scf_3ac_operand_t* dst = c->dsts->data[0]; + dst = c->dsts->data[0]; assert(!dst->code); - if (&c->list == scf_list_prev(l)) + if (&c->list == scf_list_prev(&end->list)) c->op = scf_3ac_find_operator(SCF_OP_3AC_NOP); else dst->code = end; } - if (0 == local_branch_ops->_errors->size) - goto end; - - // do all the 'error'. - for (i = local_branch_ops->_errors->size - 1; i >= 0; i--) { - - err = local_branch_ops->_errors->data[i]; - assert(err); - - scf_3ac_operand_t* dst = err->dsts->data[0]; - - if (!dst->code) { - assert(err->error); - - node = err->error; - err->error = NULL; - - tail = scf_list_tail(d->_3ac_list_head); - dst->code = scf_list_data(tail, scf_3ac_code_t, list); - - ret = _scf_do_error(ast, node, d); - SCF_CHECK_ERROR(ret < 0, ret, "do error failed\n"); - } else { - // it is the 'je' when error don't happen, do nothing. - } - } - - // pop & return error code - _scf_3ac_code_dst(d->_3ac_list_head, SCF_OP_3AC_POP, NULL); - - if (_scf_3ac_code_1(d->_3ac_list_head, SCF_OP_3AC_END, NULL) < 0) { - scf_loge("\n"); - return -1; - } - - // re-fill 'error' - for (i = 0; i < local_branch_ops->_errors->size; i++) { - - scf_3ac_code_t* c = local_branch_ops->_errors->data[i]; - scf_3ac_operand_t* dst = c->dsts->data[0]; - - if (dst->code) { - next = scf_list_next(&dst->code->list); - dst->code = scf_list_data(next, scf_3ac_code_t, list); - } else { - scf_loge("'error' has a bug!\n"); - return -1; - } - } - -end: scf_branch_ops_free(local_branch_ops); - local_branch_ops = NULL; - d->branch_ops = tmp_branch_ops; + local_branch_ops = NULL; - ast->current_block = prev_block; + d->branch_ops = tmp_branch_ops; + ast->current_block = up; return 0; } @@ -1504,7 +1434,7 @@ static int _scf_op_create(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void return ret; } - jz = scf_branch_ops_code(SCF_OP_3AC_JZ, NULL, NULL); + jz = scf_3ac_jmp_code(SCF_OP_3AC_JZ, NULL, NULL); scf_list_add_tail(d->_3ac_list_head, &jz->list); ret = _scf_3ac_code_N(d->_3ac_list_head, SCF_OP_CALL, nerr, nerr->nodes, nerr->nb_nodes); @@ -1513,7 +1443,7 @@ static int _scf_op_create(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void return ret; } - jmp = scf_branch_ops_code(SCF_OP_GOTO, NULL, NULL); + jmp = scf_3ac_jmp_code(SCF_OP_GOTO, NULL, NULL); scf_list_add_tail(d->_3ac_list_head, &jmp->list); scf_vector_add(d->branch_ops->_breaks, jz); @@ -1664,8 +1594,7 @@ static int _scf_op_expr(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* scf_handler_data_t* d = data; - scf_node_t* n = nodes[0]; - int ret = _scf_expr_calculate_internal(ast, n, d); + int ret = _scf_expr_calculate_internal(ast, nodes[0], d); if (ret < 0) { scf_loge("\n"); return -1; @@ -2400,7 +2329,7 @@ static int _scf_op_logic_##name(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes if (jmp_op < 0) \ return -1; \ \ - scf_3ac_code_t* jmp = scf_branch_ops_code(jmp_op, NULL, NULL); \ + scf_3ac_code_t* jmp = scf_3ac_jmp_code(jmp_op, NULL, NULL); \ if (!jmp) \ return -ENOMEM; \ \ @@ -2429,79 +2358,82 @@ SCF_OP_LOGIC(and) SCF_OP_LOGIC(or) scf_operator_handler_t _3ac_operator_handlers[] = { - {{NULL, NULL}, SCF_OP_EXPR, _scf_op_expr}, - {{NULL, NULL}, SCF_OP_CALL, _scf_op_call}, - {{NULL, NULL}, SCF_OP_CREATE, _scf_op_create}, - - {{NULL, NULL}, SCF_OP_ARRAY_INDEX, _scf_op_array_index}, - {{NULL, NULL}, SCF_OP_POINTER, _scf_op_pointer}, - - {{NULL, NULL}, SCF_OP_VA_START, _scf_op_va_start}, - {{NULL, NULL}, SCF_OP_VA_ARG, _scf_op_va_arg}, - {{NULL, NULL}, SCF_OP_VA_END, _scf_op_va_end}, - - {{NULL, NULL}, SCF_OP_TYPE_CAST, _scf_op_type_cast}, - {{NULL, NULL}, SCF_OP_LOGIC_NOT, _scf_op_logic_not}, - {{NULL, NULL}, SCF_OP_BIT_NOT, _scf_op_bit_not}, - {{NULL, NULL}, SCF_OP_NEG, _scf_op_neg}, - {{NULL, NULL}, SCF_OP_POSITIVE, _scf_op_positive}, - - {{NULL, NULL}, SCF_OP_INC, _scf_op_inc}, - {{NULL, NULL}, SCF_OP_DEC, _scf_op_dec}, - - {{NULL, NULL}, SCF_OP_INC_POST, _scf_op_inc_post}, - {{NULL, NULL}, SCF_OP_DEC_POST, _scf_op_dec_post}, - - {{NULL, NULL}, SCF_OP_DEREFERENCE, _scf_op_dereference}, - {{NULL, NULL}, SCF_OP_ADDRESS_OF, _scf_op_address_of}, - - {{NULL, NULL}, SCF_OP_MUL, _scf_op_mul}, - {{NULL, NULL}, SCF_OP_DIV, _scf_op_div}, - {{NULL, NULL}, SCF_OP_MOD, _scf_op_mod}, - - {{NULL, NULL}, SCF_OP_ADD, _scf_op_add}, - {{NULL, NULL}, SCF_OP_SUB, _scf_op_sub}, - - {{NULL, NULL}, SCF_OP_SHL, _scf_op_shl}, - {{NULL, NULL}, SCF_OP_SHR, _scf_op_shr}, - - {{NULL, NULL}, SCF_OP_BIT_AND, _scf_op_bit_and}, - {{NULL, NULL}, SCF_OP_BIT_OR, _scf_op_bit_or}, - - {{NULL, NULL}, SCF_OP_EQ, _scf_op_eq}, - {{NULL, NULL}, SCF_OP_NE, _scf_op_ne}, - {{NULL, NULL}, SCF_OP_GT, _scf_op_gt}, - {{NULL, NULL}, SCF_OP_LT, _scf_op_lt}, - {{NULL, NULL}, SCF_OP_GE, _scf_op_ge}, - {{NULL, NULL}, SCF_OP_LE, _scf_op_le}, - - {{NULL, NULL}, SCF_OP_LOGIC_AND, _scf_op_logic_and}, - {{NULL, NULL}, SCF_OP_LOGIC_OR, _scf_op_logic_or}, - - {{NULL, NULL}, SCF_OP_ASSIGN, _scf_op_assign}, - {{NULL, NULL}, SCF_OP_ADD_ASSIGN, _scf_op_add_assign}, - {{NULL, NULL}, SCF_OP_SUB_ASSIGN, _scf_op_sub_assign}, - {{NULL, NULL}, SCF_OP_MUL_ASSIGN, _scf_op_mul_assign}, - {{NULL, NULL}, SCF_OP_DIV_ASSIGN, _scf_op_div_assign}, - {{NULL, NULL}, SCF_OP_MOD_ASSIGN, _scf_op_mod_assign}, - {{NULL, NULL}, SCF_OP_SHL_ASSIGN, _scf_op_shl_assign}, - {{NULL, NULL}, SCF_OP_SHR_ASSIGN, _scf_op_shr_assign}, - {{NULL, NULL}, SCF_OP_AND_ASSIGN, _scf_op_and_assign}, - {{NULL, NULL}, SCF_OP_OR_ASSIGN, _scf_op_or_assign}, - - - {{NULL, NULL}, SCF_OP_BLOCK, _scf_op_block}, - {{NULL, NULL}, SCF_OP_RETURN, _scf_op_return}, - {{NULL, NULL}, SCF_OP_BREAK, _scf_op_break}, - {{NULL, NULL}, SCF_OP_CONTINUE, _scf_op_continue}, - {{NULL, NULL}, SCF_OP_GOTO, _scf_op_goto}, - {{NULL, NULL}, SCF_LABEL, _scf_op_label}, - {{NULL, NULL}, SCF_OP_ERROR, _scf_op_error}, - - {{NULL, NULL}, SCF_OP_IF, _scf_op_if}, - {{NULL, NULL}, SCF_OP_WHILE, _scf_op_while}, - {{NULL, NULL}, SCF_OP_REPEAT, _scf_op_repeat}, - {{NULL, NULL}, SCF_OP_FOR, _scf_op_for}, + {SCF_OP_EXPR, _scf_op_expr}, + {SCF_OP_CALL, _scf_op_call}, + {SCF_OP_CREATE, _scf_op_create}, + + {SCF_OP_ARRAY_INDEX, _scf_op_array_index}, + {SCF_OP_POINTER, _scf_op_pointer}, + + {SCF_OP_VA_START, _scf_op_va_start}, + {SCF_OP_VA_ARG, _scf_op_va_arg}, + {SCF_OP_VA_END, _scf_op_va_end}, + + {SCF_OP_TYPE_CAST, _scf_op_type_cast}, + {SCF_OP_LOGIC_NOT, _scf_op_logic_not}, + {SCF_OP_BIT_NOT, _scf_op_bit_not}, + {SCF_OP_NEG, _scf_op_neg}, + {SCF_OP_POSITIVE, _scf_op_positive}, + + {SCF_OP_INC, _scf_op_inc}, + {SCF_OP_DEC, _scf_op_dec}, + + {SCF_OP_INC_POST, _scf_op_inc_post}, + {SCF_OP_DEC_POST, _scf_op_dec_post}, + + {SCF_OP_DEREFERENCE, _scf_op_dereference}, + {SCF_OP_ADDRESS_OF, _scf_op_address_of}, + + {SCF_OP_MUL, _scf_op_mul}, + {SCF_OP_DIV, _scf_op_div}, + {SCF_OP_MOD, _scf_op_mod}, + + {SCF_OP_ADD, _scf_op_add}, + {SCF_OP_SUB, _scf_op_sub}, + + {SCF_OP_SHL, _scf_op_shl}, + {SCF_OP_SHR, _scf_op_shr}, + + {SCF_OP_BIT_AND, _scf_op_bit_and}, + {SCF_OP_BIT_OR, _scf_op_bit_or}, + + {SCF_OP_EQ, _scf_op_eq}, + {SCF_OP_NE, _scf_op_ne}, + {SCF_OP_GT, _scf_op_gt}, + {SCF_OP_LT, _scf_op_lt}, + {SCF_OP_GE, _scf_op_ge}, + {SCF_OP_LE, _scf_op_le}, + + {SCF_OP_LOGIC_AND, _scf_op_logic_and}, + {SCF_OP_LOGIC_OR, _scf_op_logic_or}, + + {SCF_OP_ASSIGN, _scf_op_assign}, + {SCF_OP_ADD_ASSIGN, _scf_op_add_assign}, + {SCF_OP_SUB_ASSIGN, _scf_op_sub_assign}, + {SCF_OP_MUL_ASSIGN, _scf_op_mul_assign}, + {SCF_OP_DIV_ASSIGN, _scf_op_div_assign}, + {SCF_OP_MOD_ASSIGN, _scf_op_mod_assign}, + {SCF_OP_SHL_ASSIGN, _scf_op_shl_assign}, + {SCF_OP_SHR_ASSIGN, _scf_op_shr_assign}, + {SCF_OP_AND_ASSIGN, _scf_op_and_assign}, + {SCF_OP_OR_ASSIGN, _scf_op_or_assign}, + + + {SCF_OP_BLOCK, _scf_op_block}, + {SCF_OP_RETURN, _scf_op_return}, + {SCF_OP_BREAK, _scf_op_break}, + {SCF_OP_CONTINUE, _scf_op_continue}, + {SCF_OP_GOTO, _scf_op_goto}, + {SCF_LABEL, _scf_op_label}, + + {SCF_OP_IF, _scf_op_if}, + {SCF_OP_WHILE, _scf_op_while}, + {SCF_OP_DO, _scf_op_do}, + {SCF_OP_FOR, _scf_op_for}, + + {SCF_OP_SWITCH, _scf_op_switch}, + {SCF_OP_CASE, _scf_op_case}, + {SCF_OP_DEFAULT, _scf_op_default}, }; scf_operator_handler_t* scf_find_3ac_operator_handler(const int type) @@ -2517,4 +2449,3 @@ scf_operator_handler_t* scf_find_3ac_operator_handler(const int type) return NULL; } - diff --git a/core/scf_optimizer_loop.c b/core/scf_optimizer_loop.c index 387ce87..8481a03 100644 --- a/core/scf_optimizer_loop.c +++ b/core/scf_optimizer_loop.c @@ -500,7 +500,7 @@ static int _bb_loop_add_pre_post(scf_function_t* f) if (!jmp) return -ENOMEM; - c = scf_branch_ops_code(SCF_OP_GOTO, NULL, NULL); + c = scf_3ac_jmp_code(SCF_OP_GOTO, NULL, NULL); if (!c) { scf_basic_block_free(jmp); return -ENOMEM; @@ -682,10 +682,8 @@ static int _optimize_loop_loads_saves(scf_function_t* f) for (k = 0; k < bb->dn_loads->size; k++) { dn = bb->dn_loads->data[k]; - if (dn->var->tmp_flag) { - k++; + if (dn->var->tmp_flag) continue; - } if (scf_vector_add_unique(pre->dn_loads, dn) < 0) return -1; diff --git a/docs/Naja_float.txt b/docs/Naja_float.txt new file mode 100644 index 0000000..0d92c36 --- /dev/null +++ b/docs/Naja_float.txt @@ -0,0 +1,122 @@ + Naja float instructions + + +16, fadd, +, +=, opcode = 16 +------------------------------------------------------------------------------------------------ +|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| +| 0 1 0 0 0 0|<--- rd ---->|0 | 0 0| 0 0 0 0 0 0 0 0|<--- rs1 ---->|<--- rs0 ---->| + +rd = rs0 + rs1; + + +17, fsub, -, -=, opcode = 17 +------------------------------------------------------------------------------------------------ +|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| +| 0 1 0 0 0 1|<--- rd ---->|0 | 0 0| 0 0 0 0 0 0 0 0|<--- rs1 ---->|<--- rs0 ---->| + +rd = rs0 - rs1; +------------------------------------------------------------------------------------------------ + + +18, fmul, *, *=, opcode = 18 +------------------------------------------------------------------------------------------------ +|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| +| 0 1 0 0 1 0|<--- rd ---->| s| opt | 0 0 0|<---- rs2 --->|<--- rs1 ---->|<--- rs0 ---->| + +s = 1, signed mul. + +rd = rs2 + rs0 * rs1; // opt = 0 +rd = rs2 - rs0 * rs1; // opt = 1 +rd = rs0 * rs1; // opt = 2 +------------------------------------------------------------------------------------------------ + + +19, fdiv, *, *=, opcode = 19 +------------------------------------------------------------------------------------------------ +|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| +| 0 1 0 0 1 1|<--- rd ---->| s| opt | 0 0 0|<---- rs2 --->|<--- rs1 ---->|<--- rs0 ---->| + +s = 1, signed div. + +rd = rs2 + rs0 / rs1; // opt = 0 +rd = rs2 - rs0 / rs1; // opt = 1 +rd = rs0 / rs1; // opt = 2 +------------------------------------------------------------------------------------------------ + + +20, fldr, b[i] opcode = 20 +------------------------------------------------------------------------------------------------ +|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| +| 0 1 0 1 0 0|<--- rd ---->| A| ext |<--------- simm12 ---------------->|<---- rb ---->| + +rd = *(double*)(rb + ((int64_t)simm12 << 3)); // ext = 3, +rd = *(float *)(rb + ((int64_t)simm12 << 2)); // ext = 6, SS2SD + +rb += simm12 << sh, if A = 1 +------------------------------------------------------------------------------------------------ + +21, fstr, b[i] opcode = 21 +------------------------------------------------------------------------------------------------ +|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| +| 0 1 0 1 0 1|<--- rd ---->| A| ext |<--------- simm12 ---------------->|<---- rb ---->| + +*(double*)(rb + ((int64_t)simm15 << 3) = rd; // ext = 3, +*(float *)(rb + ((int64_t)simm15 << 2) = rd; // ext = 6, SD2SS + +rb += simm12 << sh, if A = 1 +------------------------------------------------------------------------------------------------ + + +25, fcmp, >, >=, <, <=, ==, !=, opcode = 25 +------------------------------------------------------------------------------------------------ +|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| +| 0 1 1 0 0 1| 0 0 0 0 0|0 0 0| 0 0 0 0 0 0 0 0|<--- rs1 ---->|<--- rs0 ---->| + +flags = rs0 - rs1; +------------------------------------------------------------------------------------------------ + + +28, fldr, b[i << s] opcode = 28 +------------------------------------------------------------------------------------------------ +|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| +| 0 1 1 1 0 0|<--- rd ---->|PA| ext |<-------- uimm7 -->|<---- ri ---->|<---- rb ---->| + +rd = *(double*)(rb + (ri << uimm8)); // ext = 3, +rd = *(float* )(rb + (ri << uimm8)); // ext = 6, SS2SD + +rb += ri << uimm7, if PA = 1 +------------------------------------------------------------------------------------------------ + +29, fstr, b[i << s] opcode = 29 +------------------------------------------------------------------------------------------------ +|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| +| 0 1 1 1 0 1|<--- rd ---->|PA| ext |<-------- uimm7 -->|<---- ri ---->|<---- rb ---->| + +rd = *(double*)(rb + (ri << uimm8)); // ext = 3 +rd = *(float *)(rb + (ri << uimm8)); // ext = 6, SD2SS + +rb += ri << uimm7, if PA = 1 +------------------------------------------------------------------------------------------------ + +31, fmov, =, ~, -, opcode = 31 +------------------------------------------------------------------------------------------------ +|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| +| 0 1 1 1 1 1|<--- rd ---->| 0| opt | 0 0 0 0 0 0 0 0 0 0 0|<---- rs ---->| + +rd = rs; // opt = 0 +rd = rs; // opt = 1 SS2SD, +rd = rs; // opt = 2 SD2SS, +rd = -rs; // opt = 3 NEG, + +rd = rs; // opt = 4 CVTSS2SI, +rd = rs; // opt = 5 CVTSD2SI, +rd = rs; // opt = 6 CVTSS2UI, +rd = rs; // opt = 7 CVTSD2UI, + +rd = rs; // opt = c CVTSI2SS, +rd = rs; // opt = d CVTSI2SD, +rd = rs; // opt = e CVTUI2SS, +rd = rs; // opt = f CVTUI2SD, +------------------------------------------------------------------------------------------------ + + diff --git a/docs/Naja_int.txt b/docs/Naja_int.txt new file mode 100644 index 0000000..caf43fd --- /dev/null +++ b/docs/Naja_int.txt @@ -0,0 +1,314 @@ + Naja interger instructions + + +0, add, +, +=, opcode = 0 +------------------------------------------------------------------------------------------------ +|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| +| 0 0 0 0 0 0|<--- rd ---->|0 | sh |<-------- uimm8 ------>|<--- rs1 ---->|<--- rs0 ---->| + +rd = rs0 + (rs1 << IMM); // SH = 0, LSL +rd = rs0 + (rs1 >> IMM); // SH = 1, LSR +rd = rs0 + (rs1 >> IMM); // SH = 2, ASR +------------------------------------------------------------------------------------------------ +|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| +| 0 0 0 0 0 0|<--- rd ---->|1 |<----------------- uimm15 ----------------->|<--- rs0 ---->| + +rd = rs0 + (uint64_t)uimm15; +------------------------------------------------------------------------------------------------ + +1, sub, -, -=, opcode = 1 +------------------------------------------------------------------------------------------------ +|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| +| 0 0 0 0 0 1|<--- rd ---->|0 | sh |<-------- uimm8 ------>|<--- rs1 ---->|<--- rs0 ---->| + +rd = rs0 - (rs1 << IMM); // SH = 0, LSL +rd = rs0 - (rs1 >> IMM); // SH = 1, LSR +rd = rs0 - (rs1 >> IMM); // SH = 2, ASR +------------------------------------------------------------------------------------------------ +|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| +| 0 0 0 0 0 1|<--- rd ---->|1 |<----------------- uimm15 ----------------->|<--- rs0 ---->| + +rd = rs0 - (uint64_t)uimm15; +------------------------------------------------------------------------------------------------ + + +2, mul, *, *=, opcode = 2 +------------------------------------------------------------------------------------------------ +|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| +| 0 0 0 0 1 0|<--- rd ---->| s| opt | 0 0 0|<---- rs2 --->|<--- rs1 ---->|<--- rs0 ---->| + +s = 0, unsigned mul. +s = 1, signed mul. + +rd = rs2 + rs0 * rs1; // opt = 0 +rd = rs2 - rs0 * rs1; // opt = 1 +rd = rs0 * rs1; // opt = 2 +------------------------------------------------------------------------------------------------ + +3, div, *, *=, opcode = 3 +------------------------------------------------------------------------------------------------ +|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| +| 0 0 0 0 1 1|<--- rd ---->| s| opt | 0 0 0|<---- rs2 --->|<--- rs1 ---->|<--- rs0 ---->| + +s = 0, unsigned div. +s = 1, signed div. + +rd = rs2 + rs0 / rs1; // opt = 0 +rd = rs2 - rs0 / rs1; // opt = 1 +rd = rs0 / rs1; // opt = 2 +------------------------------------------------------------------------------------------------ + + +4, ldr, b[i] opcode = 4 +------------------------------------------------------------------------------------------------ +|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| +| 0 0 0 1 0 0|<--- rd ---->| A| ext |<-------- simm12 ----------------->|<---- rb ---->| + +rd = *(uint8_t* )(rs0 + (int64_t)simm12); // ext = 0, zbq +rd = *(uint16_t*)(rs0 + ((int64_t)simm12 << 1)); // ext = 1, zwq +rd = *(uint32_t*)(rs0 + ((int64_t)simm12 << 2)); // ext = 2, zlq + +rd = *(uint64_t*)(rs0 + ((int64_t)simm12 << 3)); // ext = 3, + +rd = *( int8_t* )(rs0 + (int64_t)simm12); // ext = 4, sbq +rd = *( int16_t*)(rs0 + ((int64_t)simm12 << 1)); // ext = 5, swq +rd = *( int32_t*)(rs0 + ((int64_t)simm12 << 2)); // ext = 6, slq + +rb += simm12 << SH, if A = 1 +------------------------------------------------------------------------------------------------ + +5, str, b[i] opcode = 5 +------------------------------------------------------------------------------------------------ +|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| +| 0 0 0 1 0 1|<--- rd ---->| A| ext |--------- simm12 ----------------->|<---- rb ---->| + +*(uint8_t* )(rs0 + (int64_t)simm12) = rd; // ext = 0, zbq +*(uint16_t*)(rs0 + ((int64_t)simm12 << 1)) = rd; // ext = 1, zwq +*(uint32_t*)(rs0 + ((int64_t)simm12 << 2)) = rd; // ext = 2, zlq +*(uint64_t*)(rs0 + ((int64_t)simm12 << 3)) = rd; // ext = 3 + +rb += simm12 << SH, if A = 1 +------------------------------------------------------------------------------------------------ + + +6, and, &, &=, opcode = 6 +------------------------------------------------------------------------------------------------ +|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| +| 0 0 0 1 1 0|<--- rd ---->|0 | sh |<-------- uimm8 ------>|<--- rs1 ---->|<--- rs0 ---->| + +rd = rs0 & (rs1 << IMM); // SH = 0, LSL +rd = rs0 & (rs1 >> IMM); // SH = 1, LSR +rd = rs0 & (rs1 >> IMM); // SH = 2, ASR +------------------------------------------------------------------------------------------------ +|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| +| 0 0 0 1 1 0|<--- rd ---->|1 |<----------------- uimm15 ----------------->|<--- rs0 ---->| + +rd = rs0 & (uint64_t)uimm15; +------------------------------------------------------------------------------------------------ + +7, or, |, |=, opcode = 7 +------------------------------------------------------------------------------------------------ +|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| +| 0 0 0 1 1 1|<--- rd ---->|0 | sh |<-------- uimm8 ------>|<--- rs1 ---->|<--- rs0 ---->| + +rd = rs0 | (rs1 << uimm8); // SH = 0, LSL +rd = rs0 | (rs1 >> uimm8); // SH = 1, LSR +rd = rs0 | (rs1 >> uimm8); // SH = 2, ASR + +------------------------------------------------------------------------------------------------ +|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| +| 0 0 0 1 1 1|<--- rd ---->|1 |<----------------- uimm15 ----------------->|<--- rs0 ---->| + +rd = rs0 | (uint64_t)uimm15; +------------------------------------------------------------------------------------------------ + +8, jmp, disp opcode = 8 +------------------------------------------------------------------------------------------------ +|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| +| 0 0 1 0 0 0|<-------------------------------- simm26:00 -------------------------------->| + +jmp disp; // -128M ~ 128M +------------------------------------------------------------------------------------------------ + + +9, cmp, >, >=, <, <=, ==, !=, opcode = 9 +------------------------------------------------------------------------------------------------ +|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| +| 0 0 1 0 0 1| 0 0 0 0 0|0 | sh |<-------- uimm8 ------>|<--- rs1 ---->|<--- rs0 ---->| + +flags = rs0 - (rs1 << IMM); // SH = 0, LSL +flags = rs0 - (rs1 >> IMM); // SH = 1, LSR +flags = rs0 - (rs1 >> IMM); // SH = 2, ASR + +------------------------------------------------------------------------------------------------ +|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| +| 0 0 1 0 0 1| 0 0 0 0 0|1 |<----------------- uimm15 ----------------->|<--- rs0 ---->| + +flags = rs0 - (uint64_t)uimm15; +------------------------------------------------------------------------------------------------ + + +10, jmp, reg, opcode = 10 +------------------------------------------------------------------------------------------------ +|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| +| 0 0 1 0 1 0|<--- rd ---->| 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0| + +jmp *rd; +------------------------------------------------------------------------------------------------ + +|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| +| 0 0 1 0 1 0|<----------------------------- simm21:00 -------------------->|<--- cc -->| 1| + +jcc simm21:00; // -4M ~ +4M +cc = 0, z, +cc = 1, nz, +cc = 2, ge, +cc = 3, gt, +cc = 4, le, +cc = 5, lt, +------------------------------------------------------------------------------------------------ + + +11, setcc, &&,||, opcode = 11 +------------------------------------------------------------------------------------------------ +|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| +| 0 0 1 0 1 1|<--- rd ---->| cc | 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0| + +cc = 0, z, +cc = 1, nz, +cc = 2, ge, +cc = 3, gt, +cc = 4, le, +cc = 5, lt, +------------------------------------------------------------------------------------------------ + + +12, ldr, b[i << s] opcode = 12 +------------------------------------------------------------------------------------------------ +|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| +| 0 0 1 1 0 0|<--- rd ---->|0 | ext |<------ uimm7 ----->|<---- ri ---->|<---- rb ---->| + +rd = *(uint8_t* )(rb + (ri << uimm7)); // ext = 0, zbq +rd = *(uint16_t*)(rb + (ri << uimm7)); // ext = 1, zwq +rd = *(uint32_t*)(rb + (ri << uimm7)); // ext = 2, zlq + +rd = *(uint64_t*)(rb + (ri << uimm7)); // ext = 3, + +rd = *( int8_t* )(rb + (ri << uimm7)); // ext = 4, sbq +rd = *( int16_t*)(rb + (ri << uimm7)); // ext = 5, swq +rd = *( int32_t*)(rb + (ri << uimm7)); // ext = 6, slq +------------------------------------------------------------------------------------------------ + +13, str, b[i << s] opcode = 13 +------------------------------------------------------------------------------------------------ +|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| +| 0 0 1 1 0 1|<--- rd ---->|0 | ext |<-------- uimm7 -->|<---- ri ---->|<---- rb ---->| + +rd = *(uint8_t* )(rb + (ri << uimm7)); // ext = 0, zbq +rd = *(uint16_t*)(rb + (ri << uimm7)); // ext = 1, zwq +rd = *(uint32_t*)(rb + (ri << uimm7)); // ext = 2, zlq + +rd = *(uint64_t*)(rb + (ri << uimm7)); // ext = 3, + +rd = *( int8_t* )(rb + (ri << uimm7)); // ext = 4, sbq +rd = *( int16_t*)(rb + (ri << uimm7)); // ext = 5, swq +rd = *( int32_t*)(rb + (ri << uimm7)); // ext = 6, slq +------------------------------------------------------------------------------------------------ + + +14, teq, !, opcode = 14 +------------------------------------------------------------------------------------------------ +|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| +| 0 0 1 1 1 0| 0 0 0 0 0|0 | sh |<-------- uimm8 ------>|<--- rs1 ---->|<--- rs0 ---->| + +ZF = rs0 & (rs1 << IMM); // SH = 0, LSL +ZF = rs0 & (rs1 >> IMM); // SH = 1, LSR +ZF = rs0 & (rs1 >> IMM); // SH = 2, ASR + +------------------------------------------------------------------------------------------------ +|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| +| 0 0 1 1 1 0| 0 0 0 0 0|1 |<----------------- uimm15 ----------------->|<--- rs0 ---->| + +ZF = rs0 & (uint64_t)uimm15; +------------------------------------------------------------------------------------------------ + + +15, mov, =, ~, -, opcode = 15 +------------------------------------------------------------------------------------------------ +|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| +| 0 0 1 1 1 1|<--- rd ---->|0 | 0| opt |<------------- uimm11 --------->|<---- rs ---->| + +rd = rs; // opt = 0 LSL, uimm11 = 0 +rd = rs << uimm11; // opt = 0 LSL, +rd = rs >> uimm11; // opt = 1 LSR, +rd = rs >> uimm11; // opt = 2 ASR, +rd = ~rs; // opt = 3 NOT, +rd = -rs; // opt = 4 NEG, + +------------------------------------------------------------------------------------------------ +|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| +| 0 0 1 1 1 1|<--- rd ---->|0 | 1| opt | 0 0 0 0 0 0|<--- rs1 ---->|<---- rs0---->| + +rd = rs << rs1; // opt = 0 LSL, +rd = rs >> rs1; // opt = 1 LSR, +rd = rs >> rs1; // opt = 2 ASR, + +------------------------------------------------------------------------------------------------ +|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| +| 0 0 1 1 1 1|<--- rd ---->|0 | x| opt |<------------- uimm11 --------->|<---- rs ---->| + +rd = uint8_t(rs); // x = 0, zbq, opt = 5, +rd = int8_t(rs); // x = 1, sbq, opt = 5, +rd = uint16_t(rs); // x = 0, zwq, opt = 6, +rd = int16_t(rs); // x = 1, swq, opt = 6, +rd = uint32_t(rs); // x = 0, zlq, opt = 7, +rd = int32_t(rs); // x = 1, slq, opt = 7, + +------------------------------------------------------------------------------------------------ +|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| +| 0 0 1 1 1 1|<--- rd ---->|1 | x| opt |<------------------ imm16 ------------------->| + +rd = uint64_t(imm16); // opt = 0 +rd = uint64_t(imm16) << 16; // opt = 1 +rd = uint64_t(imm16) << 32; // opt = 2 +rd = uint64_t(imm16) << 48; // opt = 3 + +rd = uint64_t(imm16); // opt = 7, NOT + +rd = uint64_t(imm16); // x = 0, zwq +rd = int64_t(imm16); // x = 1, swq +------------------------------------------------------------------------------------------------ + + +24, call, disp opcode = 24 +------------------------------------------------------------------------------------------------ +|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| +| 0 1 1 0 0 0|<-------------------------------- simm26:00 -------------------------------->| + +call disp; // -128M ~ 128M +------------------------------------------------------------------------------------------------ + +26, call, reg, opcode = 26 +------------------------------------------------------------------------------------------------ +|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| +| 0 1 1 0 1 0|<--- rd ---->| 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0| + +call *rd; +------------------------------------------------------------------------------------------------ + +42, adrp, reg, opcode = 42 +------------------------------------------------------------------------------------------------ +|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| +| 1 0 1 0 1 0|<--- rd ---->|<-------------------- simm21 ---------------------------->| + +rd = RIP + ((int64_t)simm21 << 15); // load address' high 21 bits relative to current RIP, -32G:+32G +------------------------------------------------------------------------------------------------ + +56, ret, opcode = 56 +------------------------------------------------------------------------------------------------ +|31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| +| 1 1 1 0 0 0|<-------------------------------- 00 -------------------------------->| + +ret +------------------------------------------------------------------------------------------------ + diff --git a/examples/switch_case.c b/examples/switch_case.c new file mode 100644 index 0000000..b9432c5 --- /dev/null +++ b/examples/switch_case.c @@ -0,0 +1,19 @@ +int printf(const char* fmt, ...); + +int main() +{ + int a = 0; + + switch (a) { + case 0: + printf("0\n"); + case 1: + printf("1\n"); + break; + default: + printf("default\n"); + break; + }; + + return 0; +} diff --git a/lex/scf_lex.c b/lex/scf_lex.c index 005b9f9..47aae52 100644 --- a/lex/scf_lex.c +++ b/lex/scf_lex.c @@ -18,7 +18,6 @@ static scf_lex_key_word_t key_words[] = { {"return", SCF_LEX_WORD_KEY_RETURN}, {"goto", SCF_LEX_WORD_KEY_GOTO}, - {"error", SCF_LEX_WORD_KEY_ERROR}, {"sizeof", SCF_LEX_WORD_KEY_SIZEOF}, diff --git a/parse/Makefile b/parse/Makefile index 4493884..b097b8a 100644 --- a/parse/Makefile +++ b/parse/Makefile @@ -77,7 +77,6 @@ CFILES += ../core/scf_scope.c CFILES += ../core/scf_function.c CFILES += ../core/scf_operator.c -CFILES += ../core/scf_operator_handler.c CFILES += ../core/scf_type_cast.c CFILES += ../core/scf_type_cast_i8.c @@ -148,14 +147,14 @@ CFILES += scf_struct_array.c CFILES += scf_dfa_if.c CFILES += scf_dfa_while.c -CFILES += scf_dfa_repeat.c +CFILES += scf_dfa_do.c CFILES += scf_dfa_for.c +CFILES += scf_dfa_switch.c CFILES += scf_dfa_break.c CFILES += scf_dfa_continue.c CFILES += scf_dfa_goto.c CFILES += scf_dfa_return.c -CFILES += scf_dfa_error.c CFILES += scf_dfa_label.c CFILES += scf_dfa_async.c diff --git a/parse/scf_dfa.c b/parse/scf_dfa.c index 8d7c10a..210f414 100644 --- a/parse/scf_dfa.c +++ b/parse/scf_dfa.c @@ -389,7 +389,7 @@ static int _scf_dfa_node_parse_word(scf_dfa_t* dfa, scf_dfa_node_t* node, scf_ve continue; if (SCF_DFA_SWITCH_TO == ret) { - scf_logi("\033[31m end hook: switch to %s->%s\033[0m\n", node->name, hook_node->name); + scf_logi("\033[31m end hook: switch to %s->%s\033[0m\n\n", node->name, hook_node->name); node = hook_node; ret = SCF_DFA_NEXT_WORD; diff --git a/parse/scf_dfa_block.c b/parse/scf_dfa_block.c index 20600ae..3158ee2 100644 --- a/parse/scf_dfa_block.c +++ b/parse/scf_dfa_block.c @@ -14,8 +14,6 @@ typedef struct { scf_node_t* parent_node; - scf_dfa_hook_t* hook_end; - } dfa_block_data_t; static int _block_action_entry(scf_dfa_t* dfa, scf_vector_t* words, void* data) @@ -32,8 +30,7 @@ static int _block_action_entry(scf_dfa_t* dfa, scf_vector_t* words, void* data) bd->parent_block = parse->ast->current_block; bd->parent_node = d->current_node; - bd->hook_end = SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "block_end"), SCF_DFA_HOOK_END); - assert(bd->hook_end); + SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "block_end"), SCF_DFA_HOOK_END); scf_stack_push(s, bd); @@ -56,8 +53,7 @@ static int _block_action_end(scf_dfa_t* dfa, scf_vector_t* words, void* data) scf_logi("\033[31m end bd: %p, bd->nb_lbs: %d, bd->nb_rbs: %d, s->size: %d\033[0m\n", bd, bd->nb_lbs, bd->nb_rbs, s->size); - bd->hook_end = SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "block_end"), SCF_DFA_HOOK_END); - assert(bd->hook_end); + SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "block_end"), SCF_DFA_HOOK_END); return SCF_DFA_SWITCH_TO; } @@ -101,8 +97,7 @@ static int _block_action_lb(scf_dfa_t* dfa, scf_vector_t* words, void* data) parse->ast->current_block = b; d->current_node = NULL; - bd->hook_end = SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "block_end"), SCF_DFA_HOOK_END); - assert(bd->hook_end); + SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "block_end"), SCF_DFA_HOOK_END); bd->nb_lbs++; scf_stack_push(s, bd); @@ -125,7 +120,7 @@ static int _block_action_rb(scf_dfa_t* dfa, scf_vector_t* words, void* data) scf_logi("\033[31m bd: %p, bd->nb_lbs: %d, bd->nb_rbs: %d, s->size: %d\033[0m\n", bd, bd->nb_lbs, bd->nb_rbs, s->size); - assert(bd->nb_lbs == bd->nb_rbs); + assert(bd->nb_lbs == bd->nb_rbs); parse->ast->current_block = bd->parent_block; d->current_node = bd->parent_node; @@ -150,15 +145,18 @@ 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, do, _do, _do); SCF_DFA_GET_MODULE_NODE(dfa, for, _for, _for); + SCF_DFA_GET_MODULE_NODE(dfa, switch, _switch, _switch); + SCF_DFA_GET_MODULE_NODE(dfa, switch, _case, _case); + SCF_DFA_GET_MODULE_NODE(dfa, switch, _default, _default); + SCF_DFA_GET_MODULE_NODE(dfa, break, _break, _break); SCF_DFA_GET_MODULE_NODE(dfa, continue, _continue, _continue); SCF_DFA_GET_MODULE_NODE(dfa, return, _return, _return); SCF_DFA_GET_MODULE_NODE(dfa, goto, _goto, _goto); SCF_DFA_GET_MODULE_NODE(dfa, label, label, label); - SCF_DFA_GET_MODULE_NODE(dfa, error, error, error); SCF_DFA_GET_MODULE_NODE(dfa, async, async, async); SCF_DFA_GET_MODULE_NODE(dfa, va_arg, start, va_start); @@ -177,13 +175,15 @@ static int _dfa_init_module_block(scf_dfa_t* dfa) 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, _switch); + scf_dfa_node_add_child(entry, _case); + scf_dfa_node_add_child(entry, _default); scf_dfa_node_add_child(entry, _break); scf_dfa_node_add_child(entry, _continue); scf_dfa_node_add_child(entry, _return); scf_dfa_node_add_child(entry, _goto); scf_dfa_node_add_child(entry, label); - scf_dfa_node_add_child(entry, error); scf_dfa_node_add_child(entry, async); @@ -225,7 +225,6 @@ static int _dfa_init_syntax_block(scf_dfa_t* dfa) scf_dfa_node_add_child(entry, end); scf_dfa_node_add_child(end, entry); - //scf_dfa_node_add_child(entry, entry); int i; for (i = 0; i < entry->childs->size; i++) { @@ -245,4 +244,3 @@ scf_dfa_module_t dfa_module_block = .fini_module = _dfa_fini_module_block, }; - diff --git a/parse/scf_dfa_class.c b/parse/scf_dfa_class.c index 9aeead3..21b0f07 100644 --- a/parse/scf_dfa_class.c +++ b/parse/scf_dfa_class.c @@ -11,8 +11,6 @@ typedef struct { scf_type_t* current_class; - scf_dfa_hook_t* hook_end; - int nb_lbs; int nb_rbs; @@ -28,18 +26,13 @@ static int _class_is_class(scf_dfa_t* dfa, void* word) static int _class_action_identity(scf_dfa_t* dfa, scf_vector_t* words, void* data) { - if (!data) { - printf("%s(), %d, error: \n", __func__, __LINE__); - return SCF_DFA_ERROR; - } - scf_parse_t* parse = dfa->priv; dfa_parse_data_t* d = data; class_module_data_t* md = d->module_datas[dfa_module_class.index]; scf_lex_word_t* w = words->data[words->size - 1]; if (md->current_identity) { - printf("%s(), %d, error: \n", __func__, __LINE__); + scf_loge("\n"); return SCF_DFA_ERROR; } @@ -47,7 +40,7 @@ static int _class_action_identity(scf_dfa_t* dfa, scf_vector_t* words, void* dat if (!t) { t = scf_type_alloc(w, w->text->data, SCF_STRUCT + parse->ast->nb_structs, 0); if (!t) { - printf("%s(), %d, error: \n", __func__, __LINE__); + scf_loge("\n"); return SCF_DFA_ERROR; } @@ -59,7 +52,7 @@ static int _class_action_identity(scf_dfa_t* dfa, scf_vector_t* words, void* dat md->current_identity = w; md->parent_block = parse->ast->current_block; - md->hook_end = SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "class_end"), SCF_DFA_HOOK_END); + SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "class_end"), SCF_DFA_HOOK_END); printf("\033[31m%s(), %d, t: %p, t->type: %d\033[0m\n", __func__, __LINE__, t, t->type); @@ -68,24 +61,19 @@ static int _class_action_identity(scf_dfa_t* dfa, scf_vector_t* words, void* dat static int _class_action_lb(scf_dfa_t* dfa, scf_vector_t* words, void* data) { - if (!data) { - printf("%s(), %d, error: \n", __func__, __LINE__); - return SCF_DFA_ERROR; - } - scf_parse_t* parse = dfa->priv; dfa_parse_data_t* d = data; class_module_data_t* md = d->module_datas[dfa_module_class.index]; scf_lex_word_t* w = words->data[words->size - 1]; if (!md->current_identity) { - printf("%s(), %d, error: \n", __func__, __LINE__); + scf_loge("\n"); return SCF_DFA_ERROR; } scf_type_t* t = scf_block_find_type(parse->ast->current_block, md->current_identity->text->data); if (!t) { - printf("%s(), %d, error: \n", __func__, __LINE__); + scf_loge("\n"); return SCF_DFA_ERROR; } @@ -98,8 +86,6 @@ static int _class_action_lb(scf_dfa_t* dfa, scf_vector_t* words, void* data) parse->ast->current_block = (scf_block_t*)t; - printf("%s(), %d, t: %p\n", __func__, __LINE__, t); - return SCF_DFA_NEXT_WORD; } @@ -114,7 +100,7 @@ static int _class_calculate_size(scf_dfa_t* dfa, scf_type_t* s) scf_variable_t* v = s->scope->vars->data[i]; if (v->size < 0) { - printf("%s(), %d, error: sizeof var: '%s'\n", __func__, __LINE__, v->w->text->data); + scf_loge("error: sizeof var: '%s'\n", v->w->text->data); return SCF_DFA_ERROR; } @@ -162,19 +148,12 @@ static int _class_calculate_size(scf_dfa_t* dfa, scf_type_t* s) static int _class_action_rb(scf_dfa_t* dfa, scf_vector_t* words, void* data) { - printf("%s(), %d\n", __func__, __LINE__); - - if (!data) { - printf("%s(), %d, error: \n", __func__, __LINE__); - return SCF_DFA_ERROR; - } - scf_parse_t* parse = dfa->priv; dfa_parse_data_t* d = data; class_module_data_t* md = d->module_datas[dfa_module_class.index]; if (_class_calculate_size(dfa, md->current_class) < 0) { - printf("%s(), %d, error: \n", __func__, __LINE__); + scf_loge("\n"); return SCF_DFA_ERROR; } @@ -185,24 +164,16 @@ static int _class_action_rb(scf_dfa_t* dfa, scf_vector_t* words, void* data) static int _class_action_semicolon(scf_dfa_t* dfa, scf_vector_t* words, void* data) { - printf("%s(), %d\n", __func__, __LINE__); - return SCF_DFA_OK; } static int _class_action_end(scf_dfa_t* dfa, scf_vector_t* words, void* data) { - if (!data) { - printf("%s(), %d, error: \n", __func__, __LINE__); - return SCF_DFA_ERROR; - } - scf_parse_t* parse = dfa->priv; dfa_parse_data_t* d = data; class_module_data_t* md = d->module_datas[dfa_module_class.index]; if (md->nb_rbs == md->nb_lbs) { - printf("%s(), %d, SCF_DFA_OK\n", __func__, __LINE__); parse->ast->current_block = md->parent_block; @@ -211,14 +182,12 @@ static int _class_action_end(scf_dfa_t* dfa, scf_vector_t* words, void* data) md->parent_block = NULL; md->nb_lbs = 0; md->nb_rbs = 0; - md->hook_end = NULL; return SCF_DFA_OK; } - md->hook_end = SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "class_end"), SCF_DFA_HOOK_END); + SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "class_end"), SCF_DFA_HOOK_END); - printf("%s(), %d\n", __func__, __LINE__); return SCF_DFA_SWITCH_TO; } diff --git a/parse/scf_dfa_do.c b/parse/scf_dfa_do.c new file mode 100644 index 0000000..13d3e92 --- /dev/null +++ b/parse/scf_dfa_do.c @@ -0,0 +1,226 @@ +#include"scf_dfa.h" +#include"scf_dfa_util.h" +#include"scf_parse.h" +#include"scf_stack.h" + +extern scf_dfa_module_t dfa_module_do; + +typedef struct { + int nb_lps; + int nb_rps; + + scf_block_t* parent_block; + scf_node_t* parent_node; + + scf_node_t* _do; + +} dfa_do_data_t; + + +static int _do_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_do.index]; + scf_block_t* b = NULL; + + scf_node_t* _do = scf_node_alloc(w, SCF_OP_DO, NULL); + if (!_do) { + scf_loge("node alloc failed\n"); + return SCF_DFA_ERROR; + } + + dfa_do_data_t* dd = calloc(1, sizeof(dfa_do_data_t)); + if (!dd) { + scf_loge("module data alloc failed\n"); + return SCF_DFA_ERROR; + } + + if (d->current_node) + scf_node_add_child(d->current_node, _do); + else + scf_node_add_child((scf_node_t*)parse->ast->current_block, _do); + + dd->_do = _do; + dd->parent_block = parse->ast->current_block; + dd->parent_node = d->current_node; + d->current_node = _do; + + scf_stack_push(s, dd); + + SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "do__while"), SCF_DFA_HOOK_END); + + return SCF_DFA_NEXT_WORD; +} + +static int _do_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 _do_action_lp(scf_dfa_t* dfa, scf_vector_t* words, void* data) +{ + scf_parse_t* parse = dfa->priv; + dfa_parse_data_t* d = data; + + assert(!d->expr); + d->expr_local_flag = 1; + + SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "do_rp"), SCF_DFA_HOOK_POST); + SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "do_lp_stat"), SCF_DFA_HOOK_POST); + + return SCF_DFA_NEXT_WORD; +} + +static int _do_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_do.index]; + dfa_do_data_t* dd = scf_stack_top(s); + + SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "do_lp_stat"), SCF_DFA_HOOK_POST); + + dd->nb_lps++; + + return SCF_DFA_NEXT_WORD; +} + +static int _do_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_do.index]; + dfa_do_data_t* dd = scf_stack_top(s); + + if (!d->expr) { + scf_loge("\n"); + return SCF_DFA_ERROR; + } + + dd->nb_rps++; + + if (dd->nb_rps == dd->nb_lps) { + + assert(1 == dd->_do->nb_nodes); + + scf_node_add_child(dd->_do, d->expr); + d->expr = NULL; + + d->expr_local_flag = 0; + + return SCF_DFA_SWITCH_TO; + } + + SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "do_rp"), SCF_DFA_HOOK_POST); + SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "do_lp_stat"), SCF_DFA_HOOK_POST); + + return SCF_DFA_NEXT_WORD; +} + +static int _do_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_do.index]; + dfa_do_data_t* dd = scf_stack_pop(s); + + assert(parse->ast->current_block == dd->parent_block); + + d->current_node = dd->parent_node; + + scf_logi("\033[31m do: %d, dd: %p, s->size: %d\033[0m\n", dd->_do->w->line, dd, s->size); + + free(dd); + dd = NULL; + + assert(s->size >= 0); + + return SCF_DFA_OK; +} + +static int _dfa_init_module_do(scf_dfa_t* dfa) +{ + SCF_DFA_MODULE_NODE(dfa, do, semicolon, scf_dfa_is_semicolon, _do_action_semicolon); + + SCF_DFA_MODULE_NODE(dfa, do, lp, scf_dfa_is_lp, _do_action_lp); + SCF_DFA_MODULE_NODE(dfa, do, rp, scf_dfa_is_rp, _do_action_rp); + SCF_DFA_MODULE_NODE(dfa, do, lp_stat, scf_dfa_is_lp, _do_action_lp_stat); + + SCF_DFA_MODULE_NODE(dfa, do, _do, scf_dfa_is_do, _do_action_do); + SCF_DFA_MODULE_NODE(dfa, do, _while, scf_dfa_is_while, _do_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_do.index]; + + assert(!s); + + s = scf_stack_alloc(); + if (!s) { + scf_logi("\n"); + return SCF_DFA_ERROR; + } + + d->module_datas[dfa_module_do.index] = s; + + return SCF_DFA_OK; +} + +static int _dfa_fini_module_do(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_do.index]; + + if (s) { + scf_stack_free(s); + s = NULL; + d->module_datas[dfa_module_do.index] = NULL; + } + + return SCF_DFA_OK; +} + +static int _dfa_init_syntax_do(scf_dfa_t* dfa) +{ + SCF_DFA_GET_MODULE_NODE(dfa, do, lp, lp); + SCF_DFA_GET_MODULE_NODE(dfa, do, rp, rp); + SCF_DFA_GET_MODULE_NODE(dfa, do, lp_stat, lp_stat); + SCF_DFA_GET_MODULE_NODE(dfa, do, _do, _do); + SCF_DFA_GET_MODULE_NODE(dfa, do, _while, _while); + SCF_DFA_GET_MODULE_NODE(dfa, do, semicolon, semicolon); + + SCF_DFA_GET_MODULE_NODE(dfa, expr, entry, expr); + SCF_DFA_GET_MODULE_NODE(dfa, block, entry, block); + + // do 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_do = +{ + .name = "do", + + .init_module = _dfa_init_module_do, + .init_syntax = _dfa_init_syntax_do, + + .fini_module = _dfa_fini_module_do, +}; diff --git a/parse/scf_dfa_error.c b/parse/scf_dfa_error.c deleted file mode 100644 index 3416e8a..0000000 --- a/parse/scf_dfa_error.c +++ /dev/null @@ -1,175 +0,0 @@ -#include"scf_dfa.h" -#include"scf_dfa_util.h" -#include"scf_parse.h" - -extern scf_dfa_module_t dfa_module_error; - -typedef struct { - scf_node_t* error; - -} error_module_data_t; - -static int _error_is_error(scf_dfa_t* dfa, void* word) -{ - scf_lex_word_t* w = word; - - return SCF_LEX_WORD_KEY_ERROR == w->type; -} - -static int _error_action_error(scf_dfa_t* dfa, scf_vector_t* words, void* data) -{ - scf_parse_t* parse = dfa->priv; - dfa_parse_data_t* d = data; - error_module_data_t* md = d->module_datas[dfa_module_error.index]; - scf_lex_word_t* w = words->data[words->size - 1]; - - if (d->expr) { - scf_loge("\n"); - return SCF_DFA_ERROR; - } - - scf_node_t* error = scf_node_alloc(w, SCF_OP_ERROR, NULL); - if (!error) { - scf_loge("node alloc failed\n"); - return SCF_DFA_ERROR; - } - - if (d->current_node) - scf_node_add_child(d->current_node, error); - else - scf_node_add_child((scf_node_t*)parse->ast->current_block, error); - - md->error = error; - d->expr_local_flag = 1; - - SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "error_semicolon"), SCF_DFA_HOOK_POST); - SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "error_comma"), SCF_DFA_HOOK_POST); - - return SCF_DFA_NEXT_WORD; -} - -static int _error_action_comma(scf_dfa_t* dfa, scf_vector_t* words, void* data) -{ - scf_parse_t* parse = dfa->priv; - dfa_parse_data_t* d = data; - error_module_data_t* md = d->module_datas[dfa_module_error.index]; - - if (!d->expr) { - scf_loge("\n"); - return SCF_DFA_ERROR; - } - - scf_node_add_child(md->error, d->expr); - d->expr = NULL; - - SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "error_comma"), SCF_DFA_HOOK_POST); - - return SCF_DFA_SWITCH_TO; -} - -static int _error_action_semicolon(scf_dfa_t* dfa, scf_vector_t* words, void* data) -{ - scf_parse_t* parse = dfa->priv; - dfa_parse_data_t* d = data; - error_module_data_t* md = d->module_datas[dfa_module_error.index]; - - if (!d->expr) { - scf_loge("\n"); - return SCF_DFA_ERROR; - } - - scf_node_add_child(md->error, d->expr); - d->expr = NULL; - - if (md->error->nb_nodes < 3) { - - scf_type_t* t = NULL; - - if (scf_ast_find_type_type(&t, parse->ast, SCF_VAR_INT) < 0) - return SCF_DFA_ERROR; - assert(t); - - scf_expr_t* e = scf_expr_alloc(); - - scf_variable_t* var = SCF_VAR_ALLOC_BY_TYPE(md->error->w, t, 1, 0, NULL); - SCF_CHECK_ERROR(!var, SCF_DFA_ERROR, "add default error code -1 failed\n"); - var->const_literal_flag = 1; - var->data.i = -1; - - scf_node_t* node = scf_node_alloc(NULL, var->type, var); - SCF_CHECK_ERROR(!node, SCF_DFA_ERROR, "add default error code -1 failed\n"); - - scf_expr_add_node(e, node); - scf_node_add_child(md->error, e); - e = NULL; - } - - d->expr_local_flag = 0; - md->error = NULL; - - return SCF_DFA_OK; -} - -static int _dfa_init_module_error(scf_dfa_t* dfa) -{ - SCF_DFA_MODULE_NODE(dfa, error, semicolon, scf_dfa_is_semicolon, _error_action_semicolon); - SCF_DFA_MODULE_NODE(dfa, error, comma, scf_dfa_is_comma, _error_action_comma); - SCF_DFA_MODULE_NODE(dfa, error, error, _error_is_error, _error_action_error); - - scf_parse_t* parse = dfa->priv; - dfa_parse_data_t* d = parse->dfa_data; - error_module_data_t* md = d->module_datas[dfa_module_error.index]; - - assert(!md); - - md = calloc(1, sizeof(error_module_data_t)); - if (!md) { - scf_loge("\n"); - return SCF_DFA_ERROR; - } - - d->module_datas[dfa_module_error.index] = md; - - return SCF_DFA_OK; -} - -static int _dfa_fini_module_error(scf_dfa_t* dfa) -{ - scf_parse_t* parse = dfa->priv; - dfa_parse_data_t* d = parse->dfa_data; - error_module_data_t* md = d->module_datas[dfa_module_error.index]; - - if (md) { - free(md); - md = NULL; - d->module_datas[dfa_module_error.index] = NULL; - } - - return SCF_DFA_OK; -} - -static int _dfa_init_syntax_error(scf_dfa_t* dfa) -{ - SCF_DFA_GET_MODULE_NODE(dfa, error, semicolon, semicolon); - SCF_DFA_GET_MODULE_NODE(dfa, error, comma, comma); - SCF_DFA_GET_MODULE_NODE(dfa, error, error, error); - SCF_DFA_GET_MODULE_NODE(dfa, expr, entry, expr); - - scf_dfa_node_add_child(error, expr); - scf_dfa_node_add_child(expr, comma); - scf_dfa_node_add_child(comma, expr); - scf_dfa_node_add_child(expr, semicolon); - - scf_loge("\n"); - return 0; -} - -scf_dfa_module_t dfa_module_error = -{ - .name = "error", - .init_module = _dfa_init_module_error, - .init_syntax = _dfa_init_syntax_error, - - .fini_module = _dfa_fini_module_error, -}; - diff --git a/parse/scf_dfa_for.c b/parse/scf_dfa_for.c index 7ec70b4..3970233 100644 --- a/parse/scf_dfa_for.c +++ b/parse/scf_dfa_for.c @@ -19,16 +19,8 @@ typedef struct { scf_expr_t* cond_expr; scf_vector_t* update_exprs; - scf_dfa_hook_t* hook_end; - } dfa_for_data_t; -static int _for_is_for(scf_dfa_t* dfa, void* word) -{ - scf_lex_word_t* w = word; - - return SCF_LEX_WORD_KEY_FOR == w->type; -} static int _for_is_end(scf_dfa_t* dfa, void* word) { @@ -270,7 +262,7 @@ static int _for_action_rp(scf_dfa_t* dfa, scf_vector_t* words, void* data) _for_add_exprs(fd); d->expr_local_flag = 0; - fd->hook_end = SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "for_end"), SCF_DFA_HOOK_END); + SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "for_end"), SCF_DFA_HOOK_END); return SCF_DFA_SWITCH_TO; } @@ -291,8 +283,7 @@ static int _for_action_end(scf_dfa_t* dfa, scf_vector_t* words, void* data) d->current_node = fd->parent_node; - scf_logi("\033[31m for: %d, fd: %p, hook_end: %p, s->size: %d\033[0m\n", - fd->_for->w->line, fd, fd->hook_end, s->size); + scf_logi("\033[31m for: %d, fd: %p, s->size: %d\033[0m\n", fd->_for->w->line, fd, s->size); free(fd); fd = NULL; @@ -312,7 +303,7 @@ static int _dfa_init_module_for(scf_dfa_t* dfa) SCF_DFA_MODULE_NODE(dfa, for, lp_stat, scf_dfa_is_lp, _for_action_lp_stat); SCF_DFA_MODULE_NODE(dfa, for, rp, scf_dfa_is_rp, _for_action_rp); - SCF_DFA_MODULE_NODE(dfa, for, _for, _for_is_for, _for_action_for); + SCF_DFA_MODULE_NODE(dfa, for, _for, scf_dfa_is_for, _for_action_for); scf_parse_t* parse = dfa->priv; dfa_parse_data_t* d = parse->dfa_data; diff --git a/parse/scf_dfa_function.c b/parse/scf_dfa_function.c index 7485eea..33076e4 100644 --- a/parse/scf_dfa_function.c +++ b/parse/scf_dfa_function.c @@ -8,8 +8,6 @@ typedef struct { scf_block_t* parent_block; - scf_dfa_hook_t* hook_end; - } dfa_fun_data_t; int _function_add_function(scf_dfa_t* dfa, dfa_parse_data_t* d) @@ -323,8 +321,7 @@ static int _function_action_rp(scf_dfa_t* dfa, scf_vector_t* words, void* data) scf_node_add_child((scf_node_t*)parse->ast->current_block, (scf_node_t*)d->current_function); } - fd->hook_end = SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "function_end"), SCF_DFA_HOOK_END); - assert(fd->hook_end); + SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "function_end"), SCF_DFA_HOOK_END); fd->parent_block = parse->ast->current_block; parse->ast->current_block = (scf_block_t*)d->current_function; @@ -345,7 +342,6 @@ static int _function_action_end(scf_dfa_t* dfa, scf_vector_t* words, void* data) d->current_function->node.define_flag = 1; fd->parent_block = NULL; - fd->hook_end = NULL; d->current_function = NULL; d->argc = 0; diff --git a/parse/scf_dfa_goto.c b/parse/scf_dfa_goto.c index 40869d4..176b067 100644 --- a/parse/scf_dfa_goto.c +++ b/parse/scf_dfa_goto.c @@ -4,13 +4,6 @@ extern scf_dfa_module_t dfa_module_goto; -static int _goto_is_goto(scf_dfa_t* dfa, void* word) -{ - scf_lex_word_t* w = word; - - return SCF_LEX_WORD_KEY_GOTO == w->type; -} - static int _goto_action_goto(scf_dfa_t* dfa, scf_vector_t* words, void* data) { scf_parse_t* parse = dfa->priv; @@ -58,7 +51,7 @@ static int _goto_action_semicolon(scf_dfa_t* dfa, scf_vector_t* words, void* dat static int _dfa_init_module_goto(scf_dfa_t* dfa) { - SCF_DFA_MODULE_NODE(dfa, goto, _goto, _goto_is_goto, _goto_action_goto); + SCF_DFA_MODULE_NODE(dfa, goto, _goto, scf_dfa_is_goto, _goto_action_goto); SCF_DFA_MODULE_NODE(dfa, goto, identity, scf_dfa_is_identity, _goto_action_identity); SCF_DFA_MODULE_NODE(dfa, goto, semicolon, scf_dfa_is_semicolon, _goto_action_semicolon); diff --git a/parse/scf_dfa_if.c b/parse/scf_dfa_if.c index 409e66e..dc50c61 100644 --- a/parse/scf_dfa_if.c +++ b/parse/scf_dfa_if.c @@ -1,4 +1,5 @@ #include"scf_dfa.h" +#include"scf_dfa_util.h" #include"scf_parse.h" #include"scf_stack.h" @@ -16,37 +17,8 @@ typedef struct { scf_lex_word_t* prev_else; scf_lex_word_t* next_else; - scf_dfa_hook_t* hook_end; - } dfa_if_data_t; -static int _if_is_lp(scf_dfa_t* dfa, void* word) -{ - scf_lex_word_t* w = word; - - return SCF_LEX_WORD_LP == w->type; -} - -static int _if_is_rp(scf_dfa_t* dfa, void* word) -{ - scf_lex_word_t* w = word; - - return SCF_LEX_WORD_RP == w->type; -} - -static int _if_is_if(scf_dfa_t* dfa, void* word) -{ - scf_lex_word_t* w = word; - - return SCF_LEX_WORD_KEY_IF == w->type; -} - -static int _if_is_else(scf_dfa_t* dfa, void* word) -{ - scf_lex_word_t* w = word; - - return SCF_LEX_WORD_KEY_ELSE == w->type; -} static int _if_is_end(scf_dfa_t* dfa, void* word) { @@ -178,7 +150,7 @@ static int _if_action_rp(scf_dfa_t* dfa, scf_vector_t* words, void* data) d->expr_local_flag = 0; - ifd->hook_end = SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "if_end"), SCF_DFA_HOOK_END); + SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "if_end"), SCF_DFA_HOOK_END); return SCF_DFA_SWITCH_TO; } @@ -212,7 +184,7 @@ static int _if_action_end(scf_dfa_t* dfa, scf_vector_t* words, void* data) if (1 == s->size) return SCF_DFA_NEXT_WORD; } else { - ifd->hook_end = SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "if_end"), SCF_DFA_HOOK_END); + SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "if_end"), SCF_DFA_HOOK_END); return SCF_DFA_NEXT_WORD; } } @@ -223,8 +195,7 @@ static int _if_action_end(scf_dfa_t* dfa, scf_vector_t* words, void* data) d->current_node = ifd->parent_node; - scf_logi("\033[31m if: %d, ifd: %p, hook_end: %p, s->size: %d\033[0m\n", - ifd->_if->w->line, ifd, ifd->hook_end, s->size); + scf_logi("\033[31m if: %d, ifd: %p, s->size: %d\033[0m\n", ifd->_if->w->line, ifd, s->size); free(ifd); ifd = NULL; @@ -238,12 +209,12 @@ static int _dfa_init_module_if(scf_dfa_t* dfa) { SCF_DFA_MODULE_NODE(dfa, if, end, _if_is_end, _if_action_end); - SCF_DFA_MODULE_NODE(dfa, if, lp, _if_is_lp, _if_action_lp); - SCF_DFA_MODULE_NODE(dfa, if, rp, _if_is_rp, _if_action_rp); - SCF_DFA_MODULE_NODE(dfa, if, lp_stat, _if_is_lp, _if_action_lp_stat); + SCF_DFA_MODULE_NODE(dfa, if, lp, scf_dfa_is_lp, _if_action_lp); + SCF_DFA_MODULE_NODE(dfa, if, rp, scf_dfa_is_rp, _if_action_rp); + SCF_DFA_MODULE_NODE(dfa, if, lp_stat, scf_dfa_is_lp, _if_action_lp_stat); - SCF_DFA_MODULE_NODE(dfa, if, _if, _if_is_if, _if_action_if); - SCF_DFA_MODULE_NODE(dfa, if, _else, _if_is_else, _if_action_else); + SCF_DFA_MODULE_NODE(dfa, if, _if, scf_dfa_is_if, _if_action_if); + SCF_DFA_MODULE_NODE(dfa, if, _else, scf_dfa_is_else, _if_action_else); scf_parse_t* parse = dfa->priv; dfa_parse_data_t* d = parse->dfa_data; @@ -307,7 +278,7 @@ static int _dfa_init_syntax_if(scf_dfa_t* dfa) // last else block scf_dfa_node_add_child(_else, block); - scf_loge("\n"); + scf_logi("\n"); return 0; } diff --git a/parse/scf_dfa_include.c b/parse/scf_dfa_include.c index 1367eea..20e5fe8 100644 --- a/parse/scf_dfa_include.c +++ b/parse/scf_dfa_include.c @@ -4,13 +4,6 @@ extern scf_dfa_module_t dfa_module_include; -static int _include_is_include(scf_dfa_t* dfa, void* word) -{ - scf_lex_word_t* w = word; - - return SCF_LEX_WORD_KEY_INCLUDE == w->type; -} - static int _include_action_include(scf_dfa_t* dfa, scf_vector_t* words, void* data) { scf_parse_t* parse = dfa->priv; @@ -57,7 +50,7 @@ static int _include_action_semicolon(scf_dfa_t* dfa, scf_vector_t* words, void* static int _dfa_init_module_include(scf_dfa_t* dfa) { - SCF_DFA_MODULE_NODE(dfa, include, include, _include_is_include, _include_action_include); + SCF_DFA_MODULE_NODE(dfa, include, include, scf_dfa_is_include, _include_action_include); SCF_DFA_MODULE_NODE(dfa, include, path, scf_dfa_is_const_string, _include_action_path); SCF_DFA_MODULE_NODE(dfa, include, semicolon, scf_dfa_is_semicolon, _include_action_semicolon); diff --git a/parse/scf_dfa_label.c b/parse/scf_dfa_label.c index b133909..22f50c6 100644 --- a/parse/scf_dfa_label.c +++ b/parse/scf_dfa_label.c @@ -1,15 +1,9 @@ #include"scf_dfa.h" +#include"scf_dfa_util.h" #include"scf_parse.h" extern scf_dfa_module_t dfa_module_label; -static int _label_is_colon(scf_dfa_t* dfa, void* word) -{ - scf_lex_word_t* w = word; - - return SCF_LEX_WORD_COLON == w->type; -} - static int _label_action_colon(scf_dfa_t* dfa, scf_vector_t* words, void* data) { scf_parse_t* parse = dfa->priv; @@ -37,7 +31,7 @@ static int _label_action_colon(scf_dfa_t* dfa, scf_vector_t* words, void* data) static int _dfa_init_module_label(scf_dfa_t* dfa) { - SCF_DFA_MODULE_NODE(dfa, label, label, _label_is_colon, _label_action_colon); + SCF_DFA_MODULE_NODE(dfa, label, label, scf_dfa_is_colon, _label_action_colon); return SCF_DFA_OK; } @@ -57,4 +51,3 @@ scf_dfa_module_t dfa_module_label = .init_module = _dfa_init_module_label, .init_syntax = _dfa_init_syntax_label, }; - diff --git a/parse/scf_dfa_operator.c b/parse/scf_dfa_operator.c index 39fd480..cbd2698 100644 --- a/parse/scf_dfa_operator.c +++ b/parse/scf_dfa_operator.c @@ -10,8 +10,6 @@ typedef struct { scf_lex_word_t* word_op; - scf_dfa_hook_t* hook_end; - } dfa_op_data_t; static int _operator_is_key(scf_dfa_t* dfa, void* word) @@ -270,8 +268,7 @@ static int _operator_action_rp(scf_dfa_t* dfa, scf_vector_t* words, void* data) scf_node_add_child((scf_node_t*)parse->ast->current_block, (scf_node_t*)d->current_function); } - opd->hook_end = SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "operator_end"), SCF_DFA_HOOK_END); - assert(opd->hook_end); + SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "operator_end"), SCF_DFA_HOOK_END); opd->parent_block = parse->ast->current_block; parse->ast->current_block = (scf_block_t*)d->current_function; @@ -292,7 +289,6 @@ static int _operator_action_end(scf_dfa_t* dfa, scf_vector_t* words, void* data) d->current_function->node.define_flag = 1; opd->parent_block = NULL; - opd->hook_end = NULL; d->current_function = NULL; d->argc = 0; diff --git a/parse/scf_dfa_parse.c b/parse/scf_dfa_parse.c index dcfee6a..5a4e61c 100644 --- a/parse/scf_dfa_parse.c +++ b/parse/scf_dfa_parse.c @@ -25,8 +25,9 @@ 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_do; extern scf_dfa_module_t dfa_module_for; +extern scf_dfa_module_t dfa_module_switch; #if 1 extern scf_dfa_module_t dfa_module_break; @@ -34,7 +35,6 @@ 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; @@ -65,8 +65,9 @@ scf_dfa_module_t* dfa_modules[] = &dfa_module_if, &dfa_module_while, - &dfa_module_repeat, + &dfa_module_do, &dfa_module_for, + &dfa_module_switch, #if 1 &dfa_module_break, @@ -74,7 +75,6 @@ scf_dfa_module_t* dfa_modules[] = &dfa_module_goto, &dfa_module_return, &dfa_module_label, - &dfa_module_error, &dfa_module_async, #endif &dfa_module_block, diff --git a/parse/scf_dfa_repeat.c b/parse/scf_dfa_repeat.c deleted file mode 100644 index 15ee163..0000000 --- a/parse/scf_dfa_repeat.c +++ /dev/null @@ -1,232 +0,0 @@ -#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_return.c b/parse/scf_dfa_return.c index 26098b6..a3915f3 100644 --- a/parse/scf_dfa_return.c +++ b/parse/scf_dfa_return.c @@ -4,13 +4,6 @@ extern scf_dfa_module_t dfa_module_return; -static int _return_is_return(scf_dfa_t* dfa, void* word) -{ - scf_lex_word_t* w = word; - - return SCF_LEX_WORD_KEY_RETURN == w->type; -} - static int _return_action_return(scf_dfa_t* dfa, scf_vector_t* words, void* data) { scf_parse_t* parse = dfa->priv; @@ -84,7 +77,7 @@ static int _dfa_init_module_return(scf_dfa_t* dfa) { SCF_DFA_MODULE_NODE(dfa, return, semicolon, scf_dfa_is_semicolon, _return_action_semicolon); SCF_DFA_MODULE_NODE(dfa, return, comma, scf_dfa_is_comma, _return_action_comma); - SCF_DFA_MODULE_NODE(dfa, return, _return, _return_is_return, _return_action_return); + SCF_DFA_MODULE_NODE(dfa, return, _return, scf_dfa_is_return, _return_action_return); return SCF_DFA_OK; } diff --git a/parse/scf_dfa_struct.c b/parse/scf_dfa_struct.c deleted file mode 100644 index 67f199b..0000000 --- a/parse/scf_dfa_struct.c +++ /dev/null @@ -1,545 +0,0 @@ -#include"scf_dfa.h" -#include"scf_dfa_util.h" -#include"scf_parse.h" - -extern scf_dfa_module_t dfa_module_struct; - -static int _struct_is__struct(scf_dfa_t* dfa, void* word) -{ - scf_lex_word_t* w = word; - return SCF_LEX_WORD_KEY_STRUCT == w->type; -} - -static int _struct_action_identity(scf_dfa_t* dfa, scf_vector_t* words, void* data) -{ - scf_parse_t* parse = dfa->priv; - scf_lex_word_t* w1 = words->data[words->size - 1]; - scf_type_t* t = NULL; - dfa_parse_data_t* d = data; - - if (!d->root_struct) { - t = scf_block_find_type(parse->ast->current_block, w1->text->data); - if (!t) { - t = scf_type_alloc(w1, w1->text->data, SCF_STRUCT + parse->ast->nb_structs++, 0); - if (!t) { - scf_loge("\n"); - return SCF_DFA_ERROR; - } - - scf_scope_push_type(parse->ast->current_block->scope, t); - } else { - if (t->type < SCF_STRUCT) { - scf_loge("struct name '%s' is same to base type\n", w1->text->data); - return SCF_DFA_ERROR; - } - } - - d->root_struct = t; - d->current_struct = t; - d->current_type = t; - d->nb_lbs = 0; - d->nb_rbs = 0; - - scf_logd("t: %p, d->current_type: %p\n", t, d->current_type); - } else { - if (!d->current_struct) { - scf_loge("\n"); - return SCF_DFA_ERROR; - } - - if (!d->current_struct->scope) { - scf_loge("\n"); - return SCF_DFA_ERROR; - } - - t = d->current_struct; - while (t) { - if (!strcmp(w1->text->data, t->name->data)) - break; - t = t->parent; - } - - if (!t) { - t = scf_scope_find_type(d->current_struct->scope, w1->text->data); - if (!t) { - t = scf_type_alloc(w1, w1->text->data, SCF_STRUCT + parse->ast->nb_structs++, 0); - if (!t) { - printf("%s(), %d, error: \n", __func__, __LINE__); - return SCF_DFA_ERROR; - } - - scf_scope_push_type(d->current_struct->scope, t); - - t->parent = d->current_struct; - } - } - - d->current_type = t; - scf_logd("t: %p, d->current_type: %p\n", t, d->current_type); - } - return SCF_DFA_NEXT_WORD; -} - -static int _struct_action_lb(scf_dfa_t* dfa, scf_vector_t* words, void* data) -{ - scf_parse_t* parse = dfa->priv; - - if (words->size < 3) { - printf("%s(), %d, words->size: %d\n", __func__, __LINE__, words->size); - return SCF_DFA_ERROR; - } - - scf_lex_word_t* w0 = words->data[words->size - 3]; - scf_lex_word_t* w1 = words->data[words->size - 2]; - scf_lex_word_t* w2 = words->data[words->size - 1]; - - if (SCF_LEX_WORD_ASSIGN == w1->type) - return SCF_DFA_NEXT_SYNTAX; - - assert(SCF_LEX_WORD_KEY_STRUCT == w0->type); - - scf_type_t* t = NULL; - dfa_parse_data_t* d = data; - - if (0 == d->nb_lbs) { - t = scf_block_find_type(parse->ast->current_block, w1->text->data); - - } else if (d->nb_lbs > 0) { - t = scf_scope_find_type(d->current_struct->scope, w1->text->data); - - } else { - scf_loge("\n"); - return SCF_DFA_ERROR; - } - - if (!t) { - scf_loge("type '%s' not found\n", w1->text->data); - return SCF_DFA_ERROR; - } - - if (t->scope) { - scf_loge("repeated define struct '%s'\n", w1->text->data); - return SCF_DFA_ERROR; - } - - t->scope = scf_scope_alloc(w2, t->name->data); - if (!t->scope) { - scf_loge("scope alloc failed\n"); - return SCF_DFA_ERROR; - } - - d->current_struct = t; - d->nb_lbs++; - - scf_logi("t: %p, d->current_type: %p\n", t, d->current_type); - - return SCF_DFA_NEXT_WORD; -} - -static scf_type_t* _struct_find_proper_type(scf_dfa_t* dfa, scf_type_t* s, int type) -{ - scf_parse_t* parse = dfa->priv; - - char* name = NULL; - while (s) { - assert(s->scope); - - scf_type_t* t = scf_scope_find_type_type(s->scope, type); - if (!t) - continue; - - name = t->name->data; - if (t->scope) { - return t; - } - - s = s->parent; - } - - scf_type_t* t = scf_block_find_type_type(parse->ast->current_block, type); - if (!t) - t = scf_block_find_type(parse->ast->current_block, name); - - return t; -} - -static int _struct_calculate_size(scf_dfa_t* dfa, scf_type_t* s) -{ - scf_parse_t* parse = dfa->priv; - - int size = 0; - int i; - for (i = 0; i < s->scope->vars->size; i++) { - - scf_variable_t* v = s->scope->vars->data[i]; - - if (v->size <= 0) { - assert(0 == v->nb_pointers); - - if (v->type < SCF_STRUCT) { - scf_loge("v: '%s'\n", v->w->text->data); - return SCF_DFA_ERROR; - } - - scf_type_t* t = _struct_find_proper_type(dfa, s, v->type); - if (!t) { - scf_loge("can't find proper type of v: '%s'\n", v->w->text->data); - return SCF_DFA_ERROR; - } - - v->type = t->type; - v->size = t->size; - } - - int align; - if (1 == v->size) - align = 1; - else if (2 == v->size) - align = 2; - else if (v->size <= 4) - align = 4; - else - align = 8; - - v->offset = (size + align - 1) / align * align; - - if (v->nb_dimentions > 0) { - int j; - int capacity = 1; - - for (j = 0; j < v->nb_dimentions; j++) { - if (v->dimentions[j] < 0) { - scf_loge("v: '%s'\n", v->w->text->data); - return SCF_DFA_ERROR; - - } else if (0 == v->dimentions[j]) { - - if (j < v->nb_dimentions - 1) { - scf_loge("v: '%s'\n", v->w->text->data); - return SCF_DFA_ERROR; - } - } - - capacity *= v->dimentions[j]; - } - - v->capacity = capacity; - size = v->offset + v->size * v->capacity; - } else { - size = v->offset + v->size; - } - - scf_logi("struct '%s', member: '%s', offset: %d, size: %d, v->dim: %d, v->capacity: %d\n", - s->name->data, v->w->text->data, v->offset, v->size, v->nb_dimentions, v->capacity); - } - s->size = size; - - scf_logi("struct '%s', size: %d\n", s->name->data, s->size); - return 0; -} - -static int _struct_action_rb(scf_dfa_t* dfa, scf_vector_t* words, void* data) -{ - scf_parse_t* parse = dfa->priv; - dfa_parse_data_t* d = data; - - if (_struct_calculate_size(dfa, d->current_struct) < 0) { - scf_loge("\n"); - return SCF_DFA_ERROR; - } - - d->current_type = d->current_struct; - d->current_struct = d->current_struct->parent; - d->nb_rbs++; - return SCF_DFA_NEXT_WORD; -} - -static int _struct_action_ls(scf_dfa_t* dfa, scf_vector_t* words, void* data) -{ - scf_parse_t* parse = dfa->priv; - dfa_parse_data_t* d = data; - - if (!d->current_var) { - scf_loge("\n"); - return SCF_DFA_ERROR; - } - - assert(!d->expr); - - SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "struct_rs"), SCF_DFA_HOOK_POST); - - d->nb_lss++; - - scf_variable_add_array_dimention(d->current_var, -1); - - return SCF_DFA_NEXT_WORD; -} - -static int _struct_action_rs(scf_dfa_t* dfa, scf_vector_t* words, void* data) -{ - scf_parse_t* parse = dfa->priv; - dfa_parse_data_t* d = data; - - if (!d->current_var) { - scf_loge("\n"); - return SCF_DFA_ERROR; - } - - if (!d->expr) { - scf_loge("\n"); - return SCF_DFA_ERROR; - } - - while (d->expr->parent) - d->expr = d->expr->parent; - - scf_variable_t* r = NULL; - if (scf_expr_calculate(parse->ast, d->expr, &r) < 0) { - scf_loge("\n"); - return SCF_DFA_ERROR; - } - - assert(d->nb_rss < d->current_var->nb_dimentions); - d->current_var->dimentions[d->nb_rss] = r->data.i; - - scf_loge("d->expr: %p, r->data.i: %d\n", d->expr, r->data.i); - - d->nb_rss++; - assert(d->nb_rss == d->nb_lss); - - scf_expr_free(d->expr); - d->expr = NULL; - - scf_variable_free(r); - r = NULL; - - return SCF_DFA_SWITCH_TO; -} - -static int _struct_action_semicolon(scf_dfa_t* dfa, scf_vector_t* words, void* data) -{ - dfa_parse_data_t* d = data; - - d->nb_pointers = 0; - d->const_flag = 0; - - if (d->nb_rbs == d->nb_lbs) { - scf_logi("SCF_DFA_OK\n"); - - d->root_struct = NULL; - d->current_struct = NULL; - d->current_type = NULL; - d->nb_lbs = 0; - d->nb_rbs = 0; - return SCF_DFA_OK; - - } else if (d->nb_rbs > d->nb_lbs) { - scf_loge("\n"); - return SCF_DFA_ERROR; - } - - scf_logi("SCF_DFA_NEXT_WORD\n"); - return SCF_DFA_NEXT_WORD; -} - -static int _struct_action_comma(scf_dfa_t* dfa, scf_vector_t* words, void* data) -{ - dfa_parse_data_t* d = data; - - d->nb_pointers = 0; - d->const_flag = 0; - - return SCF_DFA_NEXT_WORD; -} - -static int _struct_action_star(scf_dfa_t* dfa, scf_vector_t* words, void* data) -{ - dfa_parse_data_t* d = data; - - d->nb_pointers++; - return SCF_DFA_NEXT_WORD; -} - -static int _struct_action_base_type(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]; - - d->current_type = scf_block_find_type(parse->ast->current_block, w->text->data); - if (!d->current_type) { - scf_loge("\n"); - return SCF_DFA_ERROR; - } - - return SCF_DFA_NEXT_WORD; -} - -static int _struct_action_var(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_logi("w: %s\n", w->text->data); - - scf_variable_t* var = scf_scope_find_variable(d->current_struct->scope, w->text->data); - if (var) { - scf_loge("repeated declaration: %s\n", w->text->data); - return SCF_DFA_ERROR; - } - - if (0 == d->nb_pointers) { - if (d->nb_rbs < d->nb_lbs) { - - scf_type_t* t = d->current_struct; - - scf_logd("t: %p, d->current_type: %p\n", t, d->current_type); - - while (t) { - if (t->type == d->current_type->type) { - - scf_loge("recursive member var declaration of struct type: %s, var name: %s\n", - t->name->data, w->text->data); - return SCF_DFA_ERROR; - } - t = t->parent; - } - } - } - - var = SCF_VAR_ALLOC_BY_TYPE(w, d->current_type, 0, d->nb_pointers, NULL); - if (!var) { - scf_loge("\n"); - return SCF_DFA_ERROR; - } - scf_scope_push_var(d->current_struct->scope, var); - - d->current_var = var; - d->nb_lss = 0; - d->nb_rss = 0; - - scf_logi("type: %d, nb_pointers: %d, var: %s, line: %d, pos: %d\n\n", - var->type, var->nb_pointers, - var->w->text->data, var->w->line, var->w->pos); - - return SCF_DFA_NEXT_WORD; -} - -static int _dfa_init_module_struct(scf_dfa_t* dfa) -{ - SCF_DFA_MODULE_ENTRY(dfa, struct); - - SCF_DFA_MODULE_NODE(dfa, struct, _struct, _struct_is__struct, NULL); - SCF_DFA_MODULE_NODE(dfa, struct, lb, scf_dfa_is_lb, _struct_action_lb); - SCF_DFA_MODULE_NODE(dfa, struct, rb, scf_dfa_is_rb, _struct_action_rb); - SCF_DFA_MODULE_NODE(dfa, struct, identity, scf_dfa_is_identity, _struct_action_identity); - SCF_DFA_MODULE_NODE(dfa, struct, semicolon, scf_dfa_is_semicolon, _struct_action_semicolon); - - SCF_DFA_MODULE_NODE(dfa, struct, base_type, scf_dfa_is_base_type, _struct_action_base_type); - SCF_DFA_MODULE_NODE(dfa, struct, var, scf_dfa_is_identity, _struct_action_var); - SCF_DFA_MODULE_NODE(dfa, struct, star, scf_dfa_is_star, _struct_action_star); - SCF_DFA_MODULE_NODE(dfa, struct, comma, scf_dfa_is_comma, _struct_action_comma); - - SCF_DFA_MODULE_NODE(dfa, struct, ls, scf_dfa_is_ls, _struct_action_ls); - SCF_DFA_MODULE_NODE(dfa, struct, rs, scf_dfa_is_rs, _struct_action_rs); - - return SCF_DFA_OK; -} - -static int _dfa_init_syntax_struct(scf_dfa_t* dfa) -{ - SCF_DFA_GET_MODULE_NODE(dfa, struct, entry, entry); - - SCF_DFA_GET_MODULE_NODE(dfa, struct, _struct, _struct); - SCF_DFA_GET_MODULE_NODE(dfa, struct, lb, lb); - SCF_DFA_GET_MODULE_NODE(dfa, struct, rb, rb); - SCF_DFA_GET_MODULE_NODE(dfa, struct, identity, identity); - SCF_DFA_GET_MODULE_NODE(dfa, struct, semicolon, semicolon); - - SCF_DFA_GET_MODULE_NODE(dfa, struct, base_type, base_type); - SCF_DFA_GET_MODULE_NODE(dfa, struct, var, var); - SCF_DFA_GET_MODULE_NODE(dfa, struct, star, star); - SCF_DFA_GET_MODULE_NODE(dfa, struct, comma, comma); - - SCF_DFA_GET_MODULE_NODE(dfa, struct, ls, ls); - SCF_DFA_GET_MODULE_NODE(dfa, struct, rs, rs); - - SCF_DFA_GET_MODULE_NODE(dfa, expr, entry, expr); - - - scf_vector_add(dfa->syntaxes, entry); - scf_dfa_node_add_child(entry, _struct); - - // struct start - scf_dfa_node_add_child(_struct, identity); - - // only struct declaration - scf_dfa_node_add_child(identity, semicolon); - - // struct define start - scf_dfa_node_add_child(identity, lb); - - // empty struct define - scf_dfa_node_add_child(lb, rb); - - // recursive internal struct define - scf_dfa_node_add_child(lb, _struct); - - // end current struct define, if root struct then end all struct define - scf_dfa_node_add_child(rb, semicolon); - - // recursive end struct define - scf_dfa_node_add_child(semicolon, rb); - - // next internal struct define - scf_dfa_node_add_child(semicolon, _struct); - - // internal base type member var declaration - - scf_dfa_node_add_child(lb, base_type); - // pointer var - scf_dfa_node_add_child(base_type, star); - - // multi pointer var - scf_dfa_node_add_child(star, star); - scf_dfa_node_add_child(star, var); - - // normal var - scf_dfa_node_add_child(base_type, var); - - // continuous var in same line: int a, b, *p, **pp, etc; - scf_dfa_node_add_child(var, comma); - scf_dfa_node_add_child(comma, star); - scf_dfa_node_add_child(comma, var); - - // array var - scf_dfa_node_add_child(var, ls); - scf_dfa_node_add_child(ls, expr); - scf_dfa_node_add_child(expr, rs); - scf_dfa_node_add_child(rs, ls); - scf_dfa_node_add_child(rs, semicolon); - - // end base type var define - scf_dfa_node_add_child(var, semicolon); - - // next internal base type member var - scf_dfa_node_add_child(semicolon, base_type); - - // struct type member var declaration - scf_dfa_node_add_child(identity, star); - scf_dfa_node_add_child(identity, var); - scf_dfa_node_add_child(rb, star); - scf_dfa_node_add_child(rb, var); - - scf_logi("\n"); - return 0; -} - -scf_dfa_module_t dfa_module_struct = -{ - .name = "struct", - .init_module = _dfa_init_module_struct, - .init_syntax = _dfa_init_syntax_struct, -}; - diff --git a/parse/scf_dfa_switch.c b/parse/scf_dfa_switch.c new file mode 100644 index 0000000..589279a --- /dev/null +++ b/parse/scf_dfa_switch.c @@ -0,0 +1,285 @@ +#include"scf_dfa.h" +#include"scf_dfa_util.h" +#include"scf_parse.h" +#include"scf_stack.h" + +extern scf_dfa_module_t dfa_module_switch; + +typedef struct { + int nb_lps; + int nb_rps; + + scf_block_t* parent_block; + scf_node_t* parent_node; + + scf_node_t* _switch; + scf_node_t* child; + +} dfa_switch_data_t; + +static int _switch_is_end(scf_dfa_t* dfa, void* word) +{ + return 1; +} + +static int _switch_action_switch(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_switch.index]; + + scf_node_t* _switch = scf_node_alloc(w, SCF_OP_SWITCH, NULL); + if (!_switch) { + scf_loge("node alloc failed\n"); + return SCF_DFA_ERROR; + } + + dfa_switch_data_t* sd = calloc(1, sizeof(dfa_switch_data_t)); + if (!sd) { + scf_loge("module data alloc failed\n"); + return SCF_DFA_ERROR; + } + + if (d->current_node) + scf_node_add_child(d->current_node, _switch); + else + scf_node_add_child((scf_node_t*)parse->ast->current_block, _switch); + + sd->_switch = _switch; + sd->parent_block = parse->ast->current_block; + sd->parent_node = d->current_node; + d->current_node = _switch; + + scf_stack_push(s, sd); + + return SCF_DFA_NEXT_WORD; +} + +static int _switch_action_lp(scf_dfa_t* dfa, scf_vector_t* words, void* data) +{ + scf_parse_t* parse = dfa->priv; + dfa_parse_data_t* d = data; + + assert(!d->expr); + d->expr_local_flag = 1; + + SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "switch_rp"), SCF_DFA_HOOK_POST); + SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "switch_lp_stat"), SCF_DFA_HOOK_POST); + + return SCF_DFA_NEXT_WORD; +} + +static int _switch_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_switch.index]; + dfa_switch_data_t* sd = scf_stack_top(s); + + SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "switch_lp_stat"), SCF_DFA_HOOK_POST); + + sd->nb_lps++; + + return SCF_DFA_NEXT_WORD; +} + +static int _switch_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_stack_t* s = d->module_datas[dfa_module_switch.index]; + dfa_switch_data_t* sd = scf_stack_top(s); + + if (!d->expr) { + scf_loge("\n"); + return SCF_DFA_ERROR; + } + + sd->nb_rps++; + + if (sd->nb_rps == sd->nb_lps) { + + assert(0 == sd->_switch->nb_nodes); + + scf_node_add_child(sd->_switch, d->expr); + d->expr = NULL; + d->expr_local_flag = 0; + + SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "switch_end"), SCF_DFA_HOOK_END); + + return SCF_DFA_SWITCH_TO; + } + + SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "switch_rp"), SCF_DFA_HOOK_POST); + SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "switch_lp_stat"), SCF_DFA_HOOK_POST); + + return SCF_DFA_NEXT_WORD; +} + +static int _switch_action_case(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_switch.index]; + dfa_switch_data_t* sd = scf_stack_top(s); + + assert(!d->expr); + d->expr_local_flag = 1; + + sd->child = scf_node_alloc(w, SCF_OP_CASE, NULL); + if (!sd->child) + return SCF_DFA_ERROR; + + scf_node_add_child((scf_node_t*)parse->ast->current_block, sd->child); + + return SCF_DFA_NEXT_WORD; +} + +static int _switch_action_default(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_switch.index]; + dfa_switch_data_t* sd = scf_stack_top(s); + + assert(!d->expr); + + sd->child = scf_node_alloc(w, SCF_OP_DEFAULT, NULL); + if (!sd->child) + return SCF_DFA_ERROR; + + scf_node_add_child((scf_node_t*)parse->ast->current_block, sd->child); + + return SCF_DFA_NEXT_WORD; +} + +static int _switch_action_colon(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_switch.index]; + dfa_switch_data_t* sd = scf_stack_top(s); + + if (SCF_OP_CASE == sd->child->type) { + + if (!d->expr) { + scf_loge("NOT found the expr for case\n"); + return SCF_DFA_ERROR; + } + + scf_node_add_child(sd->child, d->expr); + d->expr = NULL; + d->expr_local_flag = 0; + + } else { + assert(SCF_OP_DEFAULT == sd->child->type); + assert(!d->expr); + } + + return SCF_DFA_OK; +} + +static int _switch_action_end(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_switch.index]; + dfa_switch_data_t* sd = scf_stack_pop(s); + + assert(parse->ast->current_block == sd->parent_block); + + d->current_node = sd->parent_node; + + scf_logi("\033[31m switch: %d, sd: %p, s->size: %d\033[0m\n", sd->_switch->w->line, sd, s->size); + + free(sd); + sd = NULL; + + assert(s->size >= 0); + + return SCF_DFA_OK; +} + +static int _dfa_init_module_switch(scf_dfa_t* dfa) +{ + SCF_DFA_MODULE_NODE(dfa, switch, lp, scf_dfa_is_lp, _switch_action_lp); + SCF_DFA_MODULE_NODE(dfa, switch, rp, scf_dfa_is_rp, _switch_action_rp); + SCF_DFA_MODULE_NODE(dfa, switch, lp_stat, scf_dfa_is_lp, _switch_action_lp_stat); + SCF_DFA_MODULE_NODE(dfa, switch, colon, scf_dfa_is_colon, _switch_action_colon); + + SCF_DFA_MODULE_NODE(dfa, switch, _switch, scf_dfa_is_switch, _switch_action_switch); + SCF_DFA_MODULE_NODE(dfa, switch, _case, scf_dfa_is_case, _switch_action_case); + SCF_DFA_MODULE_NODE(dfa, switch, _default, scf_dfa_is_default, _switch_action_default); + SCF_DFA_MODULE_NODE(dfa, switch, end, _switch_is_end, _switch_action_end); + + scf_parse_t* parse = dfa->priv; + dfa_parse_data_t* d = parse->dfa_data; + scf_stack_t* s = d->module_datas[dfa_module_switch.index]; + + assert(!s); + + s = scf_stack_alloc(); + if (!s) { + scf_logi("\n"); + return SCF_DFA_ERROR; + } + + d->module_datas[dfa_module_switch.index] = s; + + return SCF_DFA_OK; +} + +static int _dfa_fini_module_switch(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_switch.index]; + + if (s) { + scf_stack_free(s); + s = NULL; + d->module_datas[dfa_module_switch.index] = NULL; + } + + return SCF_DFA_OK; +} + +static int _dfa_init_syntax_switch(scf_dfa_t* dfa) +{ + SCF_DFA_GET_MODULE_NODE(dfa, switch, lp, lp); + SCF_DFA_GET_MODULE_NODE(dfa, switch, rp, rp); + SCF_DFA_GET_MODULE_NODE(dfa, switch, lp_stat, lp_stat); + SCF_DFA_GET_MODULE_NODE(dfa, switch, colon, colon); + + SCF_DFA_GET_MODULE_NODE(dfa, switch, _switch, _switch); + SCF_DFA_GET_MODULE_NODE(dfa, switch, _case, _case); + SCF_DFA_GET_MODULE_NODE(dfa, switch, _default, _default); + SCF_DFA_GET_MODULE_NODE(dfa, switch, end, end); + + SCF_DFA_GET_MODULE_NODE(dfa, expr, entry, expr); + SCF_DFA_GET_MODULE_NODE(dfa, block, entry, block); + + scf_dfa_node_add_child(_switch, lp); + scf_dfa_node_add_child(lp, expr); + scf_dfa_node_add_child(expr, rp); + scf_dfa_node_add_child(rp, block); + + scf_dfa_node_add_child(_case, expr); + scf_dfa_node_add_child(expr, colon); + scf_dfa_node_add_child(_default, colon); + + scf_logi("\n"); + return 0; +} + +scf_dfa_module_t dfa_module_switch = +{ + .name = "switch", + + .init_module = _dfa_init_module_switch, + .init_syntax = _dfa_init_syntax_switch, + + .fini_module = _dfa_fini_module_switch, +}; diff --git a/parse/scf_dfa_util.h b/parse/scf_dfa_util.h index b4868a6..4db002c 100644 --- a/parse/scf_dfa_util.h +++ b/parse/scf_dfa_util.h @@ -130,6 +130,13 @@ static inline int scf_dfa_is_sizeof(scf_dfa_t* dfa, void* word) return SCF_LEX_WORD_KEY_SIZEOF == w->type; } +static inline int scf_dfa_is_include(scf_dfa_t* dfa, void* word) +{ + scf_lex_word_t* w = word; + + return SCF_LEX_WORD_KEY_INCLUDE == w->type; +} + static inline int scf_dfa_is_vargs(scf_dfa_t* dfa, void* word) { scf_lex_word_t* w = word; @@ -256,6 +263,13 @@ static inline int scf_dfa_is_return(scf_dfa_t* dfa, void* word) return SCF_LEX_WORD_KEY_RETURN == w->type; } +static inline int scf_dfa_is_goto(scf_dfa_t* dfa, void* word) +{ + scf_lex_word_t* w = word; + + return SCF_LEX_WORD_KEY_GOTO == w->type; +} + static inline int scf_dfa_is_exit(scf_dfa_t* dfa, void* word) { scf_lex_word_t* w = word; @@ -312,6 +326,20 @@ static inline int scf_dfa_is_end_for(scf_dfa_t* dfa, void* word) return SCF_LEX_WORD_KEY_END_FOR == w->type; } +static inline int scf_dfa_is_switch(scf_dfa_t* dfa, void* word) +{ + scf_lex_word_t* w = word; + + return SCF_LEX_WORD_KEY_SWITCH == w->type; +} + +static inline int scf_dfa_is_default(scf_dfa_t* dfa, void* word) +{ + scf_lex_word_t* w = word; + + return SCF_LEX_WORD_KEY_DEFAULT == w->type; +} + static inline int scf_dfa_is_case(scf_dfa_t* dfa, void* word) { scf_lex_word_t* w = word; diff --git a/parse/scf_dfa_var.c b/parse/scf_dfa_var.c index 99e839b..fae3d66 100644 --- a/parse/scf_dfa_var.c +++ b/parse/scf_dfa_var.c @@ -6,13 +6,6 @@ extern scf_dfa_module_t dfa_module_var; int _expr_multi_rets(scf_expr_t* e); -static int _var_is_assign(scf_dfa_t* dfa, void* word) -{ - scf_lex_word_t* w = word; - - return SCF_LEX_WORD_ASSIGN == w->type; -} - int _check_recursive(scf_type_t* parent, scf_type_t* child, scf_lex_word_t* w) { if (child->type == parent->type) { @@ -407,7 +400,7 @@ static int _dfa_init_module_var(scf_dfa_t* dfa) SCF_DFA_MODULE_NODE(dfa, var, ls, scf_dfa_is_ls, _var_action_ls); SCF_DFA_MODULE_NODE(dfa, var, rs, scf_dfa_is_rs, _var_action_rs); - SCF_DFA_MODULE_NODE(dfa, var, assign, _var_is_assign, _var_action_assign); + SCF_DFA_MODULE_NODE(dfa, var, assign, scf_dfa_is_assign, _var_action_assign); return SCF_DFA_OK; } diff --git a/parse/scf_dfa_while.c b/parse/scf_dfa_while.c index 48071f8..086b652 100644 --- a/parse/scf_dfa_while.c +++ b/parse/scf_dfa_while.c @@ -14,16 +14,8 @@ typedef struct { scf_node_t* _while; - scf_dfa_hook_t* hook_end; - } dfa_while_data_t; -static int _while_is_while(scf_dfa_t* dfa, void* word) -{ - scf_lex_word_t* w = word; - - return SCF_LEX_WORD_KEY_WHILE == w->type; -} static int _while_is_end(scf_dfa_t* dfa, void* word) { @@ -118,7 +110,7 @@ static int _while_action_rp(scf_dfa_t* dfa, scf_vector_t* words, void* data) d->expr_local_flag = 0; - wd->hook_end = SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "while_end"), SCF_DFA_HOOK_END); + SCF_DFA_PUSH_HOOK(scf_dfa_find_node(dfa, "while_end"), SCF_DFA_HOOK_END); return SCF_DFA_SWITCH_TO; } @@ -140,9 +132,7 @@ static int _while_action_end(scf_dfa_t* dfa, scf_vector_t* words, void* data) d->current_node = wd->parent_node; - scf_logi("\033[31m while: %d, wd: %p, hook_end: %p, s->size: %d\033[0m\n", - wd->_while->w->line, - wd, wd->hook_end, s->size); + scf_logi("\033[31m while: %d, wd: %p, s->size: %d\033[0m\n", wd->_while->w->line, wd, s->size); free(wd); wd = NULL; @@ -160,7 +150,7 @@ static int _dfa_init_module_while(scf_dfa_t* dfa) SCF_DFA_MODULE_NODE(dfa, while, rp, scf_dfa_is_rp, _while_action_rp); SCF_DFA_MODULE_NODE(dfa, while, lp_stat, scf_dfa_is_lp, _while_action_lp_stat); - SCF_DFA_MODULE_NODE(dfa, while, _while, _while_is_while, _while_action_while); + SCF_DFA_MODULE_NODE(dfa, while, _while, scf_dfa_is_while, _while_action_while); scf_parse_t* parse = dfa->priv; dfa_parse_data_t* d = parse->dfa_data; diff --git a/parse/scf_operator_handler_const.c b/parse/scf_operator_handler_const.c index ab1c403..3d175cd 100644 --- a/parse/scf_operator_handler_const.c +++ b/parse/scf_operator_handler_const.c @@ -187,16 +187,16 @@ static int _scf_op_const_block(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, if (0 == nb_nodes) return 0; - scf_handler_data_t* d = data; + scf_handler_data_t* d = data; + scf_block_t* up = ast->current_block; - scf_block_t* prev_block = ast->current_block; - ast->current_block = (scf_block_t*)(nodes[0]->parent); + ast->current_block = (scf_block_t*)(nodes[0]->parent); - int i = 0; - while (i < nb_nodes) { - scf_node_t* node = nodes[i]; + int ret; + int i; - int ret; + for (i = 0; i < nb_nodes; i++) { + scf_node_t* node = nodes[i]; if (SCF_FUNCTION == node->type) ret = __scf_op_const_call(ast, (scf_function_t*)node, data); @@ -205,41 +205,12 @@ static int _scf_op_const_block(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, if (ret < 0) { scf_loge("\n"); - ast->current_block = prev_block; + ast->current_block = up; return -1; } - - i++; - } - - ast->current_block = prev_block; - return 0; -} - -static int _scf_op_const_error(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* data) -{ - scf_handler_data_t* d = data; - - scf_block_t* b = ast->current_block; - - while (b && SCF_FUNCTION != b->node.type) { - b = (scf_block_t*)b->node.parent; - } - - SCF_CHECK_ERROR(!b, -1, "error statement must in a function\n"); - assert(SCF_FUNCTION == b->node.type); - - assert(nb_nodes >= 2); - assert(nodes); - - int i; - for (i = 0; i < nb_nodes; i++) { - - int ret = _scf_expr_calculate_internal(ast, nodes[i], d); - - SCF_CHECK_ERROR(ret < 0, -1, "expr calculate error\n"); } + ast->current_block = up; return 0; } @@ -309,7 +280,7 @@ 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) +static int _scf_op_const_do(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* data) { assert(2 == nb_nodes); @@ -349,6 +320,45 @@ static int _scf_op_const_while(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, return 0; } +static int _scf_op_const_switch(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[0]; + + assert(SCF_OP_EXPR == e->type); + + if (_scf_expr_calculate_internal(ast, e, &r) < 0) + return -1; + + if (_scf_op_const_node(ast, nodes[1], d) < 0) + return -1; + + return 0; +} + +static int _scf_op_const_case(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* data) +{ + assert(1 == nb_nodes); + + scf_handler_data_t* d = data; + scf_variable_t* r = NULL; + scf_expr_t* e = nodes[0]; + + assert(SCF_OP_EXPR == e->type); + + if (_scf_expr_calculate_internal(ast, e, &r) < 0) + return -1; + return 0; +} + +static int _scf_op_const_default(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* data) +{ + return 0; +} + static int _scf_op_const_for(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* data) { assert(4 == nb_nodes); @@ -392,10 +402,10 @@ static int __scf_op_const_call(scf_ast_t* ast, scf_function_t* f, void* data) { scf_logd("f: %p, f->node->w: %s\n", f, f->node.w->text->data); - scf_handler_data_t* d = data; + scf_handler_data_t* d = data; + scf_block_t* tmp = ast->current_block; - // save & change the current block - scf_block_t* prev_block = ast->current_block; + // change the current block ast->current_block = (scf_block_t*)f; if (_scf_op_const_block(ast, f->node.nodes, f->node.nb_nodes, d) < 0) { @@ -403,7 +413,7 @@ static int __scf_op_const_call(scf_ast_t* ast, scf_function_t* f, void* data) return -1; } - ast->current_block = prev_block; + ast->current_block = tmp; return 0; } @@ -890,79 +900,82 @@ static int _scf_op_const_va_end(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes } scf_operator_handler_t const_operator_handlers[] = { - {{NULL, NULL}, SCF_OP_EXPR, _scf_op_const_expr}, - {{NULL, NULL}, SCF_OP_CALL, _scf_op_const_call}, - - {{NULL, NULL}, SCF_OP_ARRAY_INDEX, _scf_op_const_array_index}, - {{NULL, NULL}, SCF_OP_POINTER, _scf_op_const_pointer}, - {{NULL, NULL}, SCF_OP_CREATE, _scf_op_const_create}, - - {{NULL, NULL}, SCF_OP_VA_START, _scf_op_const_va_start}, - {{NULL, NULL}, SCF_OP_VA_ARG, _scf_op_const_va_arg}, - {{NULL, NULL}, SCF_OP_VA_END, _scf_op_const_va_end}, - - {{NULL, NULL}, SCF_OP_SIZEOF, _scf_op_const_sizeof}, - {{NULL, NULL}, SCF_OP_TYPE_CAST, _scf_op_const_type_cast}, - {{NULL, NULL}, SCF_OP_LOGIC_NOT, _scf_op_const_logic_not}, - {{NULL, NULL}, SCF_OP_BIT_NOT, _scf_op_const_bit_not}, - {{NULL, NULL}, SCF_OP_NEG, _scf_op_const_neg}, - {{NULL, NULL}, SCF_OP_POSITIVE, _scf_op_const_positive}, - - {{NULL, NULL}, SCF_OP_INC, _scf_op_const_inc}, - {{NULL, NULL}, SCF_OP_DEC, _scf_op_const_dec}, - - {{NULL, NULL}, SCF_OP_INC_POST, _scf_op_const_inc_post}, - {{NULL, NULL}, SCF_OP_DEC_POST, _scf_op_const_dec_post}, - - {{NULL, NULL}, SCF_OP_DEREFERENCE, _scf_op_const_dereference}, - {{NULL, NULL}, SCF_OP_ADDRESS_OF, _scf_op_const_address_of}, - - {{NULL, NULL}, SCF_OP_MUL, _scf_op_const_mul}, - {{NULL, NULL}, SCF_OP_DIV, _scf_op_const_div}, - {{NULL, NULL}, SCF_OP_MOD, _scf_op_const_mod}, - - {{NULL, NULL}, SCF_OP_ADD, _scf_op_const_add}, - {{NULL, NULL}, SCF_OP_SUB, _scf_op_const_sub}, - - {{NULL, NULL}, SCF_OP_SHL, _scf_op_const_shl}, - {{NULL, NULL}, SCF_OP_SHR, _scf_op_const_shr}, - - {{NULL, NULL}, SCF_OP_BIT_AND, _scf_op_const_bit_and}, - {{NULL, NULL}, SCF_OP_BIT_OR, _scf_op_const_bit_or}, - - {{NULL, NULL}, SCF_OP_EQ, _scf_op_const_eq}, - {{NULL, NULL}, SCF_OP_NE, _scf_op_const_ne}, - {{NULL, NULL}, SCF_OP_GT, _scf_op_const_gt}, - {{NULL, NULL}, SCF_OP_LT, _scf_op_const_lt}, - {{NULL, NULL}, SCF_OP_GE, _scf_op_const_ge}, - {{NULL, NULL}, SCF_OP_LE, _scf_op_const_le}, - - {{NULL, NULL}, SCF_OP_LOGIC_AND, _scf_op_const_logic_and}, - {{NULL, NULL}, SCF_OP_LOGIC_OR, _scf_op_const_logic_or}, - - {{NULL, NULL}, SCF_OP_ASSIGN, _scf_op_const_assign}, - {{NULL, NULL}, SCF_OP_ADD_ASSIGN, _scf_op_const_add_assign}, - {{NULL, NULL}, SCF_OP_SUB_ASSIGN, _scf_op_const_sub_assign}, - {{NULL, NULL}, SCF_OP_MUL_ASSIGN, _scf_op_const_mul_assign}, - {{NULL, NULL}, SCF_OP_DIV_ASSIGN, _scf_op_const_div_assign}, - {{NULL, NULL}, SCF_OP_MOD_ASSIGN, _scf_op_const_mod_assign}, - {{NULL, NULL}, SCF_OP_SHL_ASSIGN, _scf_op_const_shl_assign}, - {{NULL, NULL}, SCF_OP_SHR_ASSIGN, _scf_op_const_shr_assign}, - {{NULL, NULL}, SCF_OP_AND_ASSIGN, _scf_op_const_and_assign}, - {{NULL, NULL}, SCF_OP_OR_ASSIGN, _scf_op_const_or_assign}, - - {{NULL, NULL}, SCF_OP_BLOCK, _scf_op_const_block}, - {{NULL, NULL}, SCF_OP_RETURN, _scf_op_const_return}, - {{NULL, NULL}, SCF_OP_BREAK, _scf_op_const_break}, - {{NULL, NULL}, SCF_OP_CONTINUE, _scf_op_const_continue}, - {{NULL, NULL}, SCF_OP_GOTO, _scf_op_const_goto}, - {{NULL, NULL}, SCF_LABEL, _scf_op_const_label}, - {{NULL, NULL}, SCF_OP_ERROR, _scf_op_const_error}, - - {{NULL, NULL}, SCF_OP_IF, _scf_op_const_if}, - {{NULL, NULL}, SCF_OP_WHILE, _scf_op_const_while}, - {{NULL, NULL}, SCF_OP_REPEAT, _scf_op_const_repeat}, - {{NULL, NULL}, SCF_OP_FOR, _scf_op_const_for}, + {SCF_OP_EXPR, _scf_op_const_expr}, + {SCF_OP_CALL, _scf_op_const_call}, + + {SCF_OP_ARRAY_INDEX, _scf_op_const_array_index}, + {SCF_OP_POINTER, _scf_op_const_pointer}, + {SCF_OP_CREATE, _scf_op_const_create}, + + {SCF_OP_VA_START, _scf_op_const_va_start}, + {SCF_OP_VA_ARG, _scf_op_const_va_arg}, + {SCF_OP_VA_END, _scf_op_const_va_end}, + + {SCF_OP_SIZEOF, _scf_op_const_sizeof}, + {SCF_OP_TYPE_CAST, _scf_op_const_type_cast}, + {SCF_OP_LOGIC_NOT, _scf_op_const_logic_not}, + {SCF_OP_BIT_NOT, _scf_op_const_bit_not}, + {SCF_OP_NEG, _scf_op_const_neg}, + {SCF_OP_POSITIVE, _scf_op_const_positive}, + + {SCF_OP_INC, _scf_op_const_inc}, + {SCF_OP_DEC, _scf_op_const_dec}, + + {SCF_OP_INC_POST, _scf_op_const_inc_post}, + {SCF_OP_DEC_POST, _scf_op_const_dec_post}, + + {SCF_OP_DEREFERENCE, _scf_op_const_dereference}, + {SCF_OP_ADDRESS_OF, _scf_op_const_address_of}, + + {SCF_OP_MUL, _scf_op_const_mul}, + {SCF_OP_DIV, _scf_op_const_div}, + {SCF_OP_MOD, _scf_op_const_mod}, + + {SCF_OP_ADD, _scf_op_const_add}, + {SCF_OP_SUB, _scf_op_const_sub}, + + {SCF_OP_SHL, _scf_op_const_shl}, + {SCF_OP_SHR, _scf_op_const_shr}, + + {SCF_OP_BIT_AND, _scf_op_const_bit_and}, + {SCF_OP_BIT_OR, _scf_op_const_bit_or}, + + {SCF_OP_EQ, _scf_op_const_eq}, + {SCF_OP_NE, _scf_op_const_ne}, + {SCF_OP_GT, _scf_op_const_gt}, + {SCF_OP_LT, _scf_op_const_lt}, + {SCF_OP_GE, _scf_op_const_ge}, + {SCF_OP_LE, _scf_op_const_le}, + + {SCF_OP_LOGIC_AND, _scf_op_const_logic_and}, + {SCF_OP_LOGIC_OR, _scf_op_const_logic_or}, + + {SCF_OP_ASSIGN, _scf_op_const_assign}, + {SCF_OP_ADD_ASSIGN, _scf_op_const_add_assign}, + {SCF_OP_SUB_ASSIGN, _scf_op_const_sub_assign}, + {SCF_OP_MUL_ASSIGN, _scf_op_const_mul_assign}, + {SCF_OP_DIV_ASSIGN, _scf_op_const_div_assign}, + {SCF_OP_MOD_ASSIGN, _scf_op_const_mod_assign}, + {SCF_OP_SHL_ASSIGN, _scf_op_const_shl_assign}, + {SCF_OP_SHR_ASSIGN, _scf_op_const_shr_assign}, + {SCF_OP_AND_ASSIGN, _scf_op_const_and_assign}, + {SCF_OP_OR_ASSIGN, _scf_op_const_or_assign}, + + {SCF_OP_BLOCK, _scf_op_const_block}, + {SCF_OP_RETURN, _scf_op_const_return}, + {SCF_OP_BREAK, _scf_op_const_break}, + {SCF_OP_CONTINUE, _scf_op_const_continue}, + {SCF_OP_GOTO, _scf_op_const_goto}, + {SCF_LABEL, _scf_op_const_label}, + + {SCF_OP_IF, _scf_op_const_if}, + {SCF_OP_WHILE, _scf_op_const_while}, + {SCF_OP_DO, _scf_op_const_do}, + {SCF_OP_FOR, _scf_op_const_for}, + + {SCF_OP_SWITCH, _scf_op_const_switch}, + {SCF_OP_CASE, _scf_op_const_case}, + {SCF_OP_DEFAULT, _scf_op_const_default}, }; scf_operator_handler_t* scf_find_const_operator_handler(const int type) diff --git a/parse/scf_operator_handler_expr.c b/parse/scf_operator_handler_expr.c index 4382771..ac2f9eb 100644 --- a/parse/scf_operator_handler_expr.c +++ b/parse/scf_operator_handler_expr.c @@ -661,43 +661,43 @@ static int _scf_op_expr_bit_or(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, scf_operator_handler_t expr_operator_handlers[] = { - {{NULL, NULL}, SCF_OP_EXPR, _scf_op_expr_expr}, + {SCF_OP_EXPR, _scf_op_expr_expr}, - {{NULL, NULL}, SCF_OP_ARRAY_INDEX, _scf_op_expr_array_index}, - {{NULL, NULL}, SCF_OP_POINTER, _scf_op_expr_pointer}, + {SCF_OP_ARRAY_INDEX, _scf_op_expr_array_index}, + {SCF_OP_POINTER, _scf_op_expr_pointer}, - {{NULL, NULL}, SCF_OP_SIZEOF, _scf_op_expr_sizeof}, - {{NULL, NULL}, SCF_OP_TYPE_CAST, _scf_op_expr_type_cast}, - {{NULL, NULL}, SCF_OP_LOGIC_NOT, _scf_op_expr_logic_not}, - {{NULL, NULL}, SCF_OP_BIT_NOT, _scf_op_expr_bit_not}, - {{NULL, NULL}, SCF_OP_NEG, _scf_op_expr_neg}, + {SCF_OP_SIZEOF, _scf_op_expr_sizeof}, + {SCF_OP_TYPE_CAST, _scf_op_expr_type_cast}, + {SCF_OP_LOGIC_NOT, _scf_op_expr_logic_not}, + {SCF_OP_BIT_NOT, _scf_op_expr_bit_not}, + {SCF_OP_NEG, _scf_op_expr_neg}, - {{NULL, NULL}, SCF_OP_ADDRESS_OF, _scf_op_expr_address_of}, + {SCF_OP_ADDRESS_OF, _scf_op_expr_address_of}, - {{NULL, NULL}, SCF_OP_MUL, _scf_op_expr_mul}, - {{NULL, NULL}, SCF_OP_DIV, _scf_op_expr_div}, - {{NULL, NULL}, SCF_OP_MOD, _scf_op_expr_mod}, + {SCF_OP_MUL, _scf_op_expr_mul}, + {SCF_OP_DIV, _scf_op_expr_div}, + {SCF_OP_MOD, _scf_op_expr_mod}, - {{NULL, NULL}, SCF_OP_ADD, _scf_op_expr_add}, - {{NULL, NULL}, SCF_OP_SUB, _scf_op_expr_sub}, + {SCF_OP_ADD, _scf_op_expr_add}, + {SCF_OP_SUB, _scf_op_expr_sub}, - {{NULL, NULL}, SCF_OP_SHL, _scf_op_expr_shl}, - {{NULL, NULL}, SCF_OP_SHR, _scf_op_expr_shr}, + {SCF_OP_SHL, _scf_op_expr_shl}, + {SCF_OP_SHR, _scf_op_expr_shr}, - {{NULL, NULL}, SCF_OP_BIT_AND, _scf_op_expr_bit_and}, - {{NULL, NULL}, SCF_OP_BIT_OR, _scf_op_expr_bit_or}, + {SCF_OP_BIT_AND, _scf_op_expr_bit_and}, + {SCF_OP_BIT_OR, _scf_op_expr_bit_or}, - {{NULL, NULL}, SCF_OP_EQ, _scf_op_expr_eq}, - {{NULL, NULL}, SCF_OP_NE, _scf_op_expr_ne}, - {{NULL, NULL}, SCF_OP_GT, _scf_op_expr_gt}, - {{NULL, NULL}, SCF_OP_LT, _scf_op_expr_lt}, - {{NULL, NULL}, SCF_OP_GE, _scf_op_expr_ge}, - {{NULL, NULL}, SCF_OP_LE, _scf_op_expr_le}, + {SCF_OP_EQ, _scf_op_expr_eq}, + {SCF_OP_NE, _scf_op_expr_ne}, + {SCF_OP_GT, _scf_op_expr_gt}, + {SCF_OP_LT, _scf_op_expr_lt}, + {SCF_OP_GE, _scf_op_expr_ge}, + {SCF_OP_LE, _scf_op_expr_le}, - {{NULL, NULL}, SCF_OP_LOGIC_AND, _scf_op_expr_logic_and}, - {{NULL, NULL}, SCF_OP_LOGIC_OR, _scf_op_expr_logic_or}, + {SCF_OP_LOGIC_AND, _scf_op_expr_logic_and}, + {SCF_OP_LOGIC_OR, _scf_op_expr_logic_or}, - {{NULL, NULL}, SCF_OP_ASSIGN, _scf_op_expr_assign}, + {SCF_OP_ASSIGN, _scf_op_expr_assign}, }; scf_operator_handler_t* scf_find_expr_operator_handler(const int type, const int src0_type, const int src1_type, const int ret_type) diff --git a/parse/scf_operator_handler_semantic.c b/parse/scf_operator_handler_semantic.c index cdfcdae..b227849 100644 --- a/parse/scf_operator_handler_semantic.c +++ b/parse/scf_operator_handler_semantic.c @@ -1020,22 +1020,22 @@ static int _scf_op_semantic_block(scf_ast_t* ast, scf_node_t** nodes, int nb_nod if (0 == nb_nodes) return 0; - scf_handler_data_t* d = data; + scf_handler_data_t* d = data; + scf_block_t* up = ast->current_block; - scf_block_t* prev_block = ast->current_block; - ast->current_block = (scf_block_t*)(nodes[0]->parent); + scf_variable_t** pret; + scf_node_t* node; - int i = 0; - while (i < nb_nodes) { - scf_node_t* node = nodes[i]; + int ret; + int i; - if (scf_type_is_var(node->type)) { - i++; - continue; - } + ast->current_block = (scf_block_t*)(nodes[0]->parent); - scf_variable_t** pret; - int ret; + for (i = 0; i < nb_nodes; i++) { + node = nodes[i]; + + if (scf_type_is_var(node->type)) + continue; if (SCF_FUNCTION == node->type) { pret = d->pret; @@ -1046,73 +1046,12 @@ static int _scf_op_semantic_block(scf_ast_t* ast, scf_node_t** nodes, int nb_nod if (ret < 0) { scf_loge("\n"); - ast->current_block = prev_block; - return -1; - } - - i++; - } - - ast->current_block = prev_block; - return 0; -} - -static int _scf_op_semantic_error(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* data) -{ - scf_handler_data_t* d = data; - scf_variable_t** pret = NULL; - - scf_block_t* b = ast->current_block; - - while (b && SCF_FUNCTION != b->node.type) { - b = (scf_block_t*)b->node.parent; - } - - SCF_CHECK_ERROR(!b, -1, "error statement must in a function\n"); - assert(SCF_FUNCTION == b->node.type); - - assert(nb_nodes >= 2); - assert(nodes); - - int i; - for (i = 0; i < nb_nodes; i++) { - - pret = d->pret; - d->pret = &(nodes[i]->result); - int ret = _scf_expr_calculate_internal(ast, nodes[i], d); - d->pret = pret; - - SCF_CHECK_ERROR(ret < 0, -1, "expr calculate error\n"); - } - - if (!scf_type_is_integer(nodes[0]->result->type)) { - scf_loge("1st expr in error statement should got an interger for condition\n"); - return -1; - } - - if (0 == nodes[1]->result->nb_pointers - || SCF_FUNCTION_PTR == nodes[1]->result->type) { - scf_loge("2nd expr in error statement should got a pointer to be freed, but not a function pointer\n"); - return -1; - } - - if (nb_nodes >= 3) { - if (!scf_type_is_integer(nodes[2]->result->type)) { - scf_loge("3rd expr in error statement should got an interger for return value\n"); - return -1; - } - } else if (nb_nodes < 3) { - scf_logw("error in line: %d not set return value\n", nodes[0]->parent->w->line); - } - - if (nb_nodes >= 4) { - if (SCF_VAR_CHAR != nodes[3]->result->type - || 1 != nodes[3]->result->nb_pointers) { - scf_loge("4th expr in error statement should got an format string\n"); + ast->current_block = up; return -1; } } + ast->current_block = up; return 0; } @@ -1178,7 +1117,8 @@ static int _scf_op_semantic_break(scf_ast_t* ast, scf_node_t** nodes, int nb_nod while (n && SCF_OP_WHILE != n->type - && SCF_OP_REPEAT != n->type + && SCF_OP_SWITCH != n->type + && SCF_OP_DO != n->type && SCF_OP_FOR != n->type) n = n->parent; @@ -1187,8 +1127,6 @@ static int _scf_op_semantic_break(scf_ast_t* ast, scf_node_t** nodes, int nb_nod return -1; } - assert(SCF_OP_WHILE == n->type || SCF_OP_FOR == n->type || SCF_OP_REPEAT == n->type); - if (!n->parent) { scf_loge("\n"); return -1; @@ -1279,7 +1217,7 @@ 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) +static int _scf_op_semantic_do(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* data) { assert(2 == nb_nodes); @@ -1347,6 +1285,66 @@ static int _scf_op_semantic_while(scf_ast_t* ast, scf_node_t** nodes, int nb_nod return 0; } +static int _scf_op_semantic_switch(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[0]; + + assert(SCF_OP_EXPR == e->type); + + 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; + + int ret = _scf_op_semantic_node(ast, nodes[1], d); + if (ret < 0) { + scf_loge("\n"); + return -1; + } + + return 0; +} + +static int _scf_op_semantic_case(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* data) +{ + assert(1 == nb_nodes); + + scf_handler_data_t* d = data; + scf_variable_t* r = NULL; + scf_expr_t* e = nodes[0]; + + assert(SCF_OP_EXPR == e->type); + + 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); + + return 0; +} + +static int _scf_op_semantic_default(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* data) +{ + return 0; +} + static int _scf_op_semantic_for(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes, void* data) { assert(4 == nb_nodes); @@ -1400,10 +1398,10 @@ static int __scf_op_semantic_call(scf_ast_t* ast, scf_function_t* f, void* data) { scf_logd("f: %p, f->node->w: %s\n", f, f->node.w->text->data); - scf_handler_data_t* d = data; + scf_handler_data_t* d = data; + scf_block_t* tmp = ast->current_block; - // save & change the current block - scf_block_t* prev_block = ast->current_block; + // change the current block ast->current_block = (scf_block_t*)f; if (_scf_op_semantic_block(ast, f->node.nodes, f->node.nb_nodes, d) < 0) { @@ -1411,7 +1409,7 @@ static int __scf_op_semantic_call(scf_ast_t* ast, scf_function_t* f, void* data) return -1; } - ast->current_block = prev_block; + ast->current_block = tmp; return 0; } @@ -1421,6 +1419,9 @@ static int _scf_op_semantic_call(scf_ast_t* ast, scf_node_t** nodes, int nb_node scf_handler_data_t* d = data; scf_variable_t** pret = d->pret; + scf_variable_t* v0; + scf_variable_t* v1; + scf_function_t* f; scf_node_t* parent = nodes[0]->parent; d->pret = &nodes[0]->result; @@ -1432,14 +1433,14 @@ static int _scf_op_semantic_call(scf_ast_t* ast, scf_node_t** nodes, int nb_node return -1; } - scf_variable_t* v0 = _scf_operand_get(nodes[0]); + v0 = _scf_operand_get(nodes[0]); if (SCF_FUNCTION_PTR != v0->type || !v0->func_ptr) { scf_loge("\n"); return -1; } - scf_function_t* f = v0->func_ptr; + f = v0->func_ptr; if (f->vargs_flag) { if (f->argv->size > nb_nodes - 1) { @@ -1453,8 +1454,9 @@ static int _scf_op_semantic_call(scf_ast_t* ast, scf_node_t** nodes, int nb_node int i; for (i = 0; i < f->argv->size; i++) { - scf_variable_t* v0 = f->argv->data[i]; - scf_variable_t* v1 = _scf_operand_get(nodes[i + 1]); + v0 = f->argv->data[i]; + + v1 = _scf_operand_get(nodes[i + 1]); if (SCF_VAR_VOID == v1->type && 0 == v1->nb_pointers) { scf_loge("void var should be a pointer\n"); @@ -1485,8 +1487,8 @@ static int _scf_op_semantic_expr(scf_ast_t* ast, scf_node_t** nodes, int nb_node assert(1 == nb_nodes); scf_handler_data_t* d = data; + scf_node_t* n = nodes[0]; - scf_node_t* n = nodes[0]; if (n->result) { scf_variable_free(n->result); n->result = 0; @@ -1520,9 +1522,8 @@ static int _scf_op_semantic_neg(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes { assert(1 == nb_nodes); - scf_handler_data_t* d = data; - - scf_variable_t* v0 = _scf_operand_get(nodes[0]); + scf_handler_data_t* d = data; + scf_variable_t* v0 = _scf_operand_get(nodes[0]); assert(v0); @@ -1562,10 +1563,9 @@ static int _scf_op_semantic_inc(scf_ast_t* ast, scf_node_t** nodes, int nb_nodes { assert(1 == nb_nodes); - scf_handler_data_t* d = data; - - scf_variable_t* v0 = _scf_operand_get(nodes[0]); - scf_node_t* parent = nodes[0]->parent; + scf_handler_data_t* d = data; + scf_variable_t* v0 = _scf_operand_get(nodes[0]); + scf_node_t* parent = nodes[0]->parent; assert(v0); @@ -1641,9 +1641,9 @@ static int _scf_op_semantic_dereference(scf_ast_t* ast, scf_node_t** nodes, int { assert(1 == nb_nodes); - scf_handler_data_t* d = data; + scf_handler_data_t* d = data; + scf_variable_t* v0 = _scf_operand_get(nodes[0]); - scf_variable_t* v0 = _scf_operand_get(nodes[0]); assert(v0); if (v0->nb_pointers <= 0) { @@ -1669,9 +1669,9 @@ static int _scf_op_semantic_address_of(scf_ast_t* ast, scf_node_t** nodes, int n { assert(1 == nb_nodes); - scf_handler_data_t* d = data; + scf_handler_data_t* d = data; + scf_variable_t* v0 = _scf_operand_get(nodes[0]); - scf_variable_t* v0 = _scf_operand_get(nodes[0]); assert(v0); if (v0->const_literal_flag) { @@ -1821,9 +1821,8 @@ static int _scf_op_semantic_logic_not(scf_ast_t* ast, scf_node_t** nodes, int nb { assert(1 == nb_nodes); - scf_handler_data_t* d = data; - - scf_variable_t* v0 = _scf_operand_get(nodes[0]); + scf_handler_data_t* d = data; + scf_variable_t* v0 = _scf_operand_get(nodes[0]); assert(v0); @@ -1862,9 +1861,9 @@ static int _scf_op_semantic_bit_not(scf_ast_t* ast, scf_node_t** nodes, int nb_n { assert(1 == nb_nodes); - scf_handler_data_t* d = data; + scf_handler_data_t* d = data; + scf_variable_t* v0 = _scf_operand_get(nodes[0]); - scf_variable_t* v0 = _scf_operand_get(nodes[0]); assert(v0); if (scf_variable_is_struct_pointer(v0)) { @@ -2765,81 +2764,84 @@ static int _scf_op_semantic_va_end(scf_ast_t* ast, scf_node_t** nodes, int nb_no } scf_operator_handler_t semantic_operator_handlers[] = { - {{NULL, NULL}, SCF_OP_EXPR, _scf_op_semantic_expr}, - {{NULL, NULL}, SCF_OP_CALL, _scf_op_semantic_call}, - - {{NULL, NULL}, SCF_OP_ARRAY_INDEX, _scf_op_semantic_array_index}, - {{NULL, NULL}, SCF_OP_POINTER, _scf_op_semantic_pointer}, - {{NULL, NULL}, SCF_OP_CREATE, _scf_op_semantic_create}, - - {{NULL, NULL}, SCF_OP_VA_START, _scf_op_semantic_va_start}, - {{NULL, NULL}, SCF_OP_VA_ARG, _scf_op_semantic_va_arg}, - {{NULL, NULL}, SCF_OP_VA_END, _scf_op_semantic_va_end}, - - {{NULL, NULL}, SCF_OP_CONTAINER, _scf_op_semantic_container}, - - {{NULL, NULL}, SCF_OP_SIZEOF, _scf_op_semantic_sizeof}, - {{NULL, NULL}, SCF_OP_TYPE_CAST, _scf_op_semantic_type_cast}, - {{NULL, NULL}, SCF_OP_LOGIC_NOT, _scf_op_semantic_logic_not}, - {{NULL, NULL}, SCF_OP_BIT_NOT, _scf_op_semantic_bit_not}, - {{NULL, NULL}, SCF_OP_NEG, _scf_op_semantic_neg}, - {{NULL, NULL}, SCF_OP_POSITIVE, _scf_op_semantic_positive}, - - {{NULL, NULL}, SCF_OP_INC, _scf_op_semantic_inc}, - {{NULL, NULL}, SCF_OP_DEC, _scf_op_semantic_dec}, - - {{NULL, NULL}, SCF_OP_INC_POST, _scf_op_semantic_inc_post}, - {{NULL, NULL}, SCF_OP_DEC_POST, _scf_op_semantic_dec_post}, - - {{NULL, NULL}, SCF_OP_DEREFERENCE, _scf_op_semantic_dereference}, - {{NULL, NULL}, SCF_OP_ADDRESS_OF, _scf_op_semantic_address_of}, - - {{NULL, NULL}, SCF_OP_MUL, _scf_op_semantic_mul}, - {{NULL, NULL}, SCF_OP_DIV, _scf_op_semantic_div}, - {{NULL, NULL}, SCF_OP_MOD, _scf_op_semantic_mod}, - - {{NULL, NULL}, SCF_OP_ADD, _scf_op_semantic_add}, - {{NULL, NULL}, SCF_OP_SUB, _scf_op_semantic_sub}, - - {{NULL, NULL}, SCF_OP_SHL, _scf_op_semantic_shl}, - {{NULL, NULL}, SCF_OP_SHR, _scf_op_semantic_shr}, - - {{NULL, NULL}, SCF_OP_BIT_AND, _scf_op_semantic_bit_and}, - {{NULL, NULL}, SCF_OP_BIT_OR, _scf_op_semantic_bit_or}, - - {{NULL, NULL}, SCF_OP_EQ, _scf_op_semantic_eq}, - {{NULL, NULL}, SCF_OP_NE, _scf_op_semantic_ne}, - {{NULL, NULL}, SCF_OP_GT, _scf_op_semantic_gt}, - {{NULL, NULL}, SCF_OP_LT, _scf_op_semantic_lt}, - {{NULL, NULL}, SCF_OP_GE, _scf_op_semantic_ge}, - {{NULL, NULL}, SCF_OP_LE, _scf_op_semantic_le}, - - {{NULL, NULL}, SCF_OP_LOGIC_AND, _scf_op_semantic_logic_and}, - {{NULL, NULL}, SCF_OP_LOGIC_OR, _scf_op_semantic_logic_or}, - - {{NULL, NULL}, SCF_OP_ASSIGN, _scf_op_semantic_assign}, - {{NULL, NULL}, SCF_OP_ADD_ASSIGN, _scf_op_semantic_add_assign}, - {{NULL, NULL}, SCF_OP_SUB_ASSIGN, _scf_op_semantic_sub_assign}, - {{NULL, NULL}, SCF_OP_MUL_ASSIGN, _scf_op_semantic_mul_assign}, - {{NULL, NULL}, SCF_OP_DIV_ASSIGN, _scf_op_semantic_div_assign}, - {{NULL, NULL}, SCF_OP_MOD_ASSIGN, _scf_op_semantic_mod_assign}, - {{NULL, NULL}, SCF_OP_SHL_ASSIGN, _scf_op_semantic_shl_assign}, - {{NULL, NULL}, SCF_OP_SHR_ASSIGN, _scf_op_semantic_shr_assign}, - {{NULL, NULL}, SCF_OP_AND_ASSIGN, _scf_op_semantic_and_assign}, - {{NULL, NULL}, SCF_OP_OR_ASSIGN, _scf_op_semantic_or_assign}, - - {{NULL, NULL}, SCF_OP_BLOCK, _scf_op_semantic_block}, - {{NULL, NULL}, SCF_OP_RETURN, _scf_op_semantic_return}, - {{NULL, NULL}, SCF_OP_BREAK, _scf_op_semantic_break}, - {{NULL, NULL}, SCF_OP_CONTINUE, _scf_op_semantic_continue}, - {{NULL, NULL}, SCF_OP_GOTO, _scf_op_semantic_goto}, - {{NULL, NULL}, SCF_LABEL, _scf_op_semantic_label}, - {{NULL, NULL}, SCF_OP_ERROR, _scf_op_semantic_error}, - - {{NULL, NULL}, SCF_OP_IF, _scf_op_semantic_if}, - {{NULL, NULL}, SCF_OP_WHILE, _scf_op_semantic_while}, - {{NULL, NULL}, SCF_OP_REPEAT, _scf_op_semantic_repeat}, - {{NULL, NULL}, SCF_OP_FOR, _scf_op_semantic_for}, + {SCF_OP_EXPR, _scf_op_semantic_expr}, + {SCF_OP_CALL, _scf_op_semantic_call}, + + {SCF_OP_ARRAY_INDEX, _scf_op_semantic_array_index}, + {SCF_OP_POINTER, _scf_op_semantic_pointer}, + {SCF_OP_CREATE, _scf_op_semantic_create}, + + {SCF_OP_VA_START, _scf_op_semantic_va_start}, + {SCF_OP_VA_ARG, _scf_op_semantic_va_arg}, + {SCF_OP_VA_END, _scf_op_semantic_va_end}, + + {SCF_OP_CONTAINER, _scf_op_semantic_container}, + + {SCF_OP_SIZEOF, _scf_op_semantic_sizeof}, + {SCF_OP_TYPE_CAST, _scf_op_semantic_type_cast}, + {SCF_OP_LOGIC_NOT, _scf_op_semantic_logic_not}, + {SCF_OP_BIT_NOT, _scf_op_semantic_bit_not}, + {SCF_OP_NEG, _scf_op_semantic_neg}, + {SCF_OP_POSITIVE, _scf_op_semantic_positive}, + + {SCF_OP_INC, _scf_op_semantic_inc}, + {SCF_OP_DEC, _scf_op_semantic_dec}, + + {SCF_OP_INC_POST, _scf_op_semantic_inc_post}, + {SCF_OP_DEC_POST, _scf_op_semantic_dec_post}, + + {SCF_OP_DEREFERENCE, _scf_op_semantic_dereference}, + {SCF_OP_ADDRESS_OF, _scf_op_semantic_address_of}, + + {SCF_OP_MUL, _scf_op_semantic_mul}, + {SCF_OP_DIV, _scf_op_semantic_div}, + {SCF_OP_MOD, _scf_op_semantic_mod}, + + {SCF_OP_ADD, _scf_op_semantic_add}, + {SCF_OP_SUB, _scf_op_semantic_sub}, + + {SCF_OP_SHL, _scf_op_semantic_shl}, + {SCF_OP_SHR, _scf_op_semantic_shr}, + + {SCF_OP_BIT_AND, _scf_op_semantic_bit_and}, + {SCF_OP_BIT_OR, _scf_op_semantic_bit_or}, + + {SCF_OP_EQ, _scf_op_semantic_eq}, + {SCF_OP_NE, _scf_op_semantic_ne}, + {SCF_OP_GT, _scf_op_semantic_gt}, + {SCF_OP_LT, _scf_op_semantic_lt}, + {SCF_OP_GE, _scf_op_semantic_ge}, + {SCF_OP_LE, _scf_op_semantic_le}, + + {SCF_OP_LOGIC_AND, _scf_op_semantic_logic_and}, + {SCF_OP_LOGIC_OR, _scf_op_semantic_logic_or}, + + {SCF_OP_ASSIGN, _scf_op_semantic_assign}, + {SCF_OP_ADD_ASSIGN, _scf_op_semantic_add_assign}, + {SCF_OP_SUB_ASSIGN, _scf_op_semantic_sub_assign}, + {SCF_OP_MUL_ASSIGN, _scf_op_semantic_mul_assign}, + {SCF_OP_DIV_ASSIGN, _scf_op_semantic_div_assign}, + {SCF_OP_MOD_ASSIGN, _scf_op_semantic_mod_assign}, + {SCF_OP_SHL_ASSIGN, _scf_op_semantic_shl_assign}, + {SCF_OP_SHR_ASSIGN, _scf_op_semantic_shr_assign}, + {SCF_OP_AND_ASSIGN, _scf_op_semantic_and_assign}, + {SCF_OP_OR_ASSIGN, _scf_op_semantic_or_assign}, + + {SCF_OP_BLOCK, _scf_op_semantic_block}, + {SCF_OP_RETURN, _scf_op_semantic_return}, + {SCF_OP_BREAK, _scf_op_semantic_break}, + {SCF_OP_CONTINUE, _scf_op_semantic_continue}, + {SCF_OP_GOTO, _scf_op_semantic_goto}, + {SCF_LABEL, _scf_op_semantic_label}, + + {SCF_OP_IF, _scf_op_semantic_if}, + {SCF_OP_WHILE, _scf_op_semantic_while}, + {SCF_OP_DO, _scf_op_semantic_do}, + {SCF_OP_FOR, _scf_op_semantic_for}, + + {SCF_OP_SWITCH, _scf_op_semantic_switch}, + {SCF_OP_CASE, _scf_op_semantic_case}, + {SCF_OP_DEFAULT, _scf_op_semantic_default}, }; scf_operator_handler_t* scf_find_semantic_operator_handler(const int type) diff --git a/parse/scf_parse.c b/parse/scf_parse.c index 8c4ae85..87b97a0 100644 --- a/parse/scf_parse.c +++ b/parse/scf_parse.c @@ -1881,6 +1881,8 @@ int scf_parse_compile_functions(scf_parse_t* parse, scf_vector_t* functions) return ret; } +// scf_3ac_list_print(&h); + ret = scf_3ac_split_basic_blocks(&h, f); if (ret < 0) { scf_list_clear(&h, scf_3ac_code_t, list, scf_3ac_code_free); diff --git a/parse/scf_rbtree.c b/parse/scf_rbtree.c deleted file mode 100644 index 70a2332..0000000 --- a/parse/scf_rbtree.c +++ /dev/null @@ -1,713 +0,0 @@ - -struct scf_rbtree_node_t -{ - scf_rbtree_node_t* parent; - - scf_rbtree_node_t* left; - scf_rbtree_node_t* right; - - uint16_t depth; - uint16_t bdepth; - uint8_t color; -}; - -struct scf_rbtree_t -{ - scf_rbtree_node_t* root; - scf_rbtree_node_t sentinel; -}; - -const uint8_t SCF_RBTREE_BLACK = 0; -const uint8_t SCF_RBTREE_RED = 1; - -int scf_rbtree_node_do_pt(scf_rbtree_node_t* node0, void* data); - -inline scf_rbtree_node_t* scf_rbtree_sentinel(scf_rbtree_t* tree) -{ - return &tree->sentinel; -} - -inline void scf_rbtree_init(scf_rbtree_t* tree) -{ - tree->sentinel->parent = &tree->sentinel; - tree->sentinel->left = &tree->sentinel; - tree->sentinel->right = &tree->sentinel; - - tree->sentinel->color = SCF_RBTREE_BLACK; - - tree->root = &tree->sentinel; -} - -static scf_rbtree_node_t* _rbtree_min(scf_rbtree_t* tree, scf_rbtree_node_t* root) -{ - while (root->left != &tree->sentinel) - root = root->left; - - return root; -} - -static scf_rbtree_node_t* _rbtree_max(scf_rbtree_t* tree, scf_rbtree_node_t* root) -{ - while (root->right != &tree->sentinel) - root = root->right; - - return root; -} - -scf_rbtree_node_t* scf_rbtree_min(scf_rbtree_t* tree, scf_rbtree_node_t* root) -{ - if (!tree || !root) - return NULL; - - scf_rbtree_node_t* x = _rbtree_min(tree, root); - - if (&tree->sentinel == x) - return NULL; - return x; -} - -scf_rbtree_node_t* scf_rbtree_max(scf_rbtree_t* tree, scf_rbtree_node_t* root) -{ - if (!tree || !root) - return NULL; - - scf_rbtree_node_t* x = _rbtree_max(tree, root); - - if (&tree->sentinel == x) - return NULL; - return x; -} - -static scf_rbtree_node_t* _rbtree_next(scf_rbtree_t* tree, scf_rbtree_node_t* x) -{ - if (x->right != &tree->sentinel) - return _rbtree_min(tree, x->right); - - scf_rbtree_node_t* y = x->parent; - - while (y != &tree->sentinel && x == y->right) { - x = y; - y = y->parent; - } - - return y; -} - -/* left rotate - - px px px (py) px (py) - | | | | - x x y y - / \ / \ / \ / \ - xl y --> xl yl y --> x yr --> x yr - / \ / \ / \ / \ - yl yr yr xl yl xl yl -*/ -static void _left_rotate(scf_rbtree_t* tree, scf_rbtree_node_t* x) -{ - scf_rbtree_node_t* y = x->right; - - x->right = y->left; - if (&tree->sentinel != y->left) - y->left->parent = x; - - y->parent = x->parent; - if (&tree->sentinel == x->parent) - tree->root = y; - else if (x->parent->left == x) - x->parent->left = y; - else - x->parent->right = y; - - y->left = x; - x->parent = y; -} - -/* right rotate - - py py py (px) py (px) - | | | | - y y x x - / \ / \ / \ / \ - x yr --> x xr yr --> xl y --> xl y - / \ / \ / \ / \ - xl xr xl xr yr xr yr -*/ -static void _right_rotate(scf_rbtree_t* tree, scf_rbtree_node_t* y) -{ - scf_rbtree_node_t* x = y->left; - - y->left = x->right; - if (&tree->sentinel != x->right) - x->right->parent = y; - - x->parent = y->parent; - if (&tree->sentinel == y->parent) - tree->root = x; - else if (y->parent->left == y) - y->parent->left = x; - else - y->parent->right = x; - - x->right = y; - y->parent = x; -} - -static void _rb_insert_fixup(scf_rbtree_t* tree, scf_rbtree_node_t* z) -{ -/* -gp: z's grand-parent -zp: z's parent -zu: z's uncle -*/ - scf_rbtree_node_t* y; - - while (SCF_RBTREE_RED == z->parent->color) { - - if (z->parent == z->parent->parent->left) { - - y = z->parent->parent->right; // y is z's uncle - - if (y->color == SCF_RBTREE_RED) { -/* - gp (black) - / \ -(red) zp zu (red) - | - z (red) -*/ - y->color = SCF_RBTREE_BLACK; - z->parent->color = SCF_RBTREE_BLACK; - z->parent->parent->color = SCF_RBTREE_RED; - - z = z->parent->parent; - - } else { - if (z == z->parent->right) { -/* - gp (black) gp (black) - / \ left / \ -(red) zp zu (black) ---> (red) z zu (black) - / \ / \ - zb z (red) (z', red) zp - / - zb -*/ - z = z->parent; - _left_rotate(tree, z); - } -/* - gp (red) (black) z - / \ right / \ - (black) z zu (black) ---> (z', red) zp gp (red) - / \ / / \ - (z', red) zp zb zu (black) - / - zb -*/ - z->parent->color = SCF_RBTREE_BLACK; - z->parent->parent->color = SCF_RBTREE_RED; - _right_rotate(tree, z->parent->parent); - } - } else { - y = z->parent->parent->left; // y is z's uncle - - if (y->color == SCF_RBTREE_RED) { - - y->color = SCF_RBTREE_BLACK; - z->parent->color = SCF_RBTREE_BLACK; - z->parent->parent->color = SCF_RBTREE_RED; - - z = z->parent->parent; - - } else { - if (z == z->parent->left) { -/* - gp (black) gp (black) - / \ right / \ -(black) zu zp (red) ---> (black) zu z (red) - / \ / \ - (red) z zb zp (red, z') - \ - zb -*/ - - z = z->parent; - _right_rotate(tree, z); - } - -/* - gp (red) z (black) - / \ left / \ -(black) zu z (black) ---> (red) gp zp (red, z') - / \ / \ \ - zp (red, z') (black) zu zb - \ - zb -*/ - z->parent->color = SCF_RBTREE_BLACK; - z->parent->parent->color = SCF_RBTREE_RED; - _left_rotate(tree, z->parent->parent); - } - } - } - - tree->root->color = SCF_RBTREE_BLACK; -} - -int scf_rbtree_insert(scf_rbtree_t* tree, scf_rbtree_node_t* z, scf_rbtree_node_do_pt* cmp) -{ - if (!tree || !z || !cmp) - return -1; - - scf_rbtree_node_t* y = &tree->sentinel; - scf_rbtree_node_t** px = &tree->root; - scf_rbtree_node_t* x = *px; - - while (&tree->sentinel != x) { - y = x; - - if (cmp(z, x) < 0) - px = &x->left; - else - px = &x->right; - x = *px; - } - // after 'while', y is x's parent, x is the position to insert z. - - z->parent = y; - *px = z; - - z->left = &tree->sentinel; - z->right = &tree->sentinel; - z->color = SCF_RBTREE_RED; - - _rb_insert_fixup(tree, z); - return 0; -} - -static void _rb_delete_fixup(scf_rbtree_t* tree, scf_rbtree_node_t* x) -{ - scf_rbtree_node_t* w; - - //scf_loge("y: %p, z: %p, z->parent: %p\n", y, z, z->parent); - - while (tree->root != x && SCF_RBTREE_BLACK == x->color) { - - if (x == x->parent->left) { - w = x->parent->right; - - if (SCF_RBTREE_RED == w->color) { -/* - px (black) left w (black) - / \ ---> / \ -(black2)x w (red) (red) px wr (black) - / \ / \ - (black) wl wr (black) (black2) x wl (w', black) - / \ / \ - wll wlr wll wlr -*/ - w->color == SCF_RBTREE_BLACK; - x->parent->color = SCF_RBTREE_RED; - - _left_rotate(tree, x->parent); - - w = x->parent->right; - } - - if (SCF_RBTREE_BLACK == w->left->color && SCF_RBTREE_BLACK == w->right->color) { -/* - w (black) - / \ -(red, x') px wr (black) - / \ -(black2)x wl (w', red) - / \ - wll wlr -*/ - - w->color = SCF_RBTREE_RED; - x = x->parent; - - } else { - if (SCF_RBTREE_BLACK == w->right->color) { -/* - w (black) w (black) - / \ / \ - (red) px wr (black) right (red) px wr (black) - / \ ---> / \ -(black2)x wl (w', black) (black2)x wll (black, w'') - / \ \ - (red) wll wlr (black) wl (w', red) - \ - wlr (black) -*/ - - w->left->color = SCF_RBTREE_BLACK; - w->color = SCF_RBTREE_RED; - - _right_rotate(tree, w); - w = x->parent->right; // w'' - } - -/* - w (black) w (black) - / \ / \ - (black) px wr (black) left (red, w'') wll - / \ ---> / \ - (black2) x wll (red, w'') (black) px wl (w', black) - \ / \ - wl (w', black) (black) x wlr (black) - \ - wlr (black) -*/ - w->color = x->parent->color; - x->parent->color = SCF_RBTREE_BLACK; - w->right->color = SCF_RBTREE_BLACK; - _left_rotate(tree, x->parent); - - x = tree->root; - } - } else { - w = x->parent->left; - - if (SCF_RBTREE_RED == w->color) { -/* - px (black) right w (black) - / \ ---> / \ - (red) w x (black2) (black) wl px (red) - / \ / \ -(black) wl wr (black) (black, w')wr x (black2) - / \ / \ - wrl wrr wrl wrr -*/ - w->color == SCF_RBTREE_BLACK; - x->parent->color = SCF_RBTREE_RED; - - _right_rotate(tree, x->parent); - - w = x->parent->left; - } - - if (SCF_RBTREE_BLACK == w->left->color && SCF_RBTREE_BLACK == w->right->color) { -/* - w (black) - / \ -(black) wl px (red, x') - / \ - (black, w')wr x (black2) - / \ - wrl wrr -*/ - w->color = SCF_RBTREE_RED; - x = x->parent; - - } else { - if (SCF_RBTREE_BLACK == w->left->color) { -/* - w (black) w (black) - / \ / \ -(black) wl px (red) left (black) wl px (red) - / \ ---> / \ - (black, w')wr x (black2) (black, w'') wrr x (black2) - / \ / - (black) wrl wrr (red) (red, w') wr - / - (black) wrl -*/ - w->right->color = SCF_RBTREE_BLACK; - w->color = SCF_RBTREE_RED; - - _left_rotate(tree, w); - w = x->parent->left; // w'' - } - -/* - w (black) w (black) w (black) - / \ set color / \ right / \ -(black) wl px (red) ----> (black) wl px (black) ---> (black)wl wr (w', red) - / \ / \ / \ - (black, w')wr x (black2) (red, w') wr x (black) (black)wrl px (black) - / \ / \ / \ - (red) wrl wrr (black) (black) wrl wrr (black) (black) wrr x (black) -*/ - - w->color = x->parent->color; - x->parent->color = SCF_RBTREE_BLACK; - w->left->color = SCF_RBTREE_BLACK; - _right_rotate(tree, x->parent); - - x = tree->root; - } - } - } - - x->color = SCF_RBTREE_BLACK; -} - -int scf_rbtree_delete(scf_rbtree_t* tree, scf_rbtree_node_t* z) -{ - if (!tree || !z) - return -1; - - scf_rbtree_node_t* x = NULL; - scf_rbtree_node_t* y = NULL; - - if (&tree->sentinel == z->left || &tree->sentinel == z->right) - y = z; - else - y = _rbtree_next(tree, z); - - if (&tree->sentinel != y->left) - x = y->left; - else - x = y->right; - - // y is the position to delete - x->parent = y->parent; - - if (&tree->sentinel == y->parent) { - tree->root = x; - } else if (y->parent->left == y) { - y->parent->left = x; - } else { - y->parent->right = x; - } - - uint8_t color = y->color; - - if (y != z) { - y->parent = z->parent; - y->left = z->left; - y->right = z->right; - y->color = z->color; - } - - // avoid wrong operations to these 3 pointers, only - z->parent = NULL; - z->left = NULL; - z->right = NULL; - - if (SCF_RBTREE_BLACK == color) - _rb_delete_fixup(tree, x); - - return 0; -} - -scf_rbtree_node_t* scf_rbtree_find(scf_rbtree_t* tree, void* data, scf_rbtree_node_do_pt* cmp) -{ - if (!tree || !cmp) - return NULL; - - scf_rbtree_node_t* node = tree->root; - - while (&tree->sentinel != node) { - - int ret = cmp(node, data); - - if (ret < 0) - node = node->right; - else if (ret > 0) - node = node->left; - else - return node; - } - - return NULL; -} - -int scf_rbtree_foreach(scf_rbtree_t* tree, scf_rbtree_node_t* root, void* data, scf_rbtree_node_do_pt* done) -{ - if (!tree || !root || !done) - return -1; - - if (&tree->sentinel == root) - return 0; - - int ret; - - if (&tree->sentinel != root->left) { - - ret = scf_rbtree_foreach(tree, root->left, data, done); - if (ret < 0) - return ret; - } - - ret = done(root, data); - if (ret < 0) - return ret; - - if (&tree->sentinel != root->right) { - - ret = scf_rbtree_foreach(tree, root->right, data, done); - if (ret < 0) - return ret; - } - return 0; -} - -int scf_rbtree_foreach_reverse(scf_rbtree_t* tree, scf_rbtree_node_t* root, void* data, scf_rbtree_node_do_pt* done) -{ - if (!tree || !root || !done) - return -1; - - if (&tree->sentinel == root) - return 0; - - int ret; - - if (&tree->sentinel != root->right) { - - ret = scf_rbtree_foreach_reverse(tree, root->right, data, done); - if (ret < 0) - return ret; - } - - ret = done(root, data); - if (ret < 0) - return ret; - - if (&tree->sentinel != root->left) { - - ret = scf_rbtree_foreach_reverse(tree, root->left, data, done); - if (ret < 0) - return ret; - } - return 0; -} - -int scf_printf(const char* fmt, ...); -void* calloc(uintptr_t n, uintptr_t size); -int free(void* p); - -int scf_rbtree_depth(scf_rbtree_t* tree, scf_rbtree_node_t* root) -{ - if (!tree || !root) - return -1; - - if (&tree->sentinel == root) - return 0; - - int ret; - - if (root == tree->root) { - root->depth = 1; - root->bdepth = 1; - } else if (SCF_RBTREE_BLACK == root->color) { - root->bdepth = root->parent->bdepth + 1; - root->depth = root->parent->depth + 1; - } else { - root->bdepth = root->parent->bdepth; - root->depth = root->parent->depth + 1; - } - - scf_printf("root: %p, bdepth: %d, depth: %d\n", root, root->bdepth, root->depth); - - if (&tree->sentinel != root->left) { - - ret = scf_rbtree_depth(tree, root->left); - if (ret < 0) - return ret; - } - - if (&tree->sentinel != root->right) { - - ret = scf_rbtree_depth(tree, root->right); - if (ret < 0) - return ret; - } - return 0; -} - - -struct rbtree_test_t -{ - scf_rbtree_node_t node; - int d; -}; - -static int test_cmp(scf_rbtree_node_t* node0, void* data) -{ - rbtree_test_t* v0 = (rbtree_test_t*)node0; - rbtree_test_t* v1 = (rbtree_test_t*)data; - - if (v0->d < v1->d) - return -1; - else if (v0->d > v1->d) - return 1; - return 0; -} - -static int test_find(scf_rbtree_node_t* node0, void* data) -{ - rbtree_test_t* v0 = (rbtree_test_t*)node0; - int d1 = (intptr_t)data; - - if (v0->d < d1) - return -1; - else if (v0->d > d1) - return 1; - return 0; -} - -static int test_print(scf_rbtree_node_t* node0, void* data) -{ - rbtree_test_t* v0 = (rbtree_test_t*)node0; - - scf_printf("v0->d: %d\n", v0->d); - return 0; -} - -const int N = 17; - -int main() -{ - scf_rbtree_t tree; - scf_rbtree_init(&tree); - - rbtree_test_t* d; - - int i; - for (i = 0; i < N; i++) { - d = calloc(1, sizeof(rbtree_test_t)); - - d->d = i; - - int ret = scf_rbtree_insert(&tree, &d->node, test_cmp); - if (ret < 0) - return -1; - } - - scf_rbtree_foreach(&tree, tree->root, NULL, test_print); - - scf_rbtree_depth(&tree, tree->root); - - for (i = 0; i < N / 2; i++) { - d = (rbtree_test_t*) scf_rbtree_find(&tree, (void*)(intptr_t)i, test_find); - - int ret = scf_rbtree_delete(&tree, &d->node); - - free(d); - d = NULL; - } - - scf_rbtree_foreach(&tree, tree->root, NULL, test_print); - - scf_rbtree_depth(&tree, tree->root); - - for (i = 0; i < N / 2; i++) { - d = calloc(1, sizeof(rbtree_test_t)); - - d->d = i; - - int ret = scf_rbtree_insert(&tree, &d->node, test_cmp); - if (ret < 0) - return -1; - } - scf_rbtree_foreach_reverse(&tree, tree->root, NULL, test_print); - - scf_rbtree_depth(&tree, tree->root); - return 0; -} - - -- 2.25.1