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;
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);
int scf_3ac_code_same(scf_3ac_code_t* c0, scf_3ac_code_t* c1);
#endif
-
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
SCF_LEX_WORD_KEY_RETURN, // return
SCF_LEX_WORD_KEY_GOTO, // goto
- SCF_LEX_WORD_KEY_ERROR, // error
SCF_LEX_WORD_KEY_SIZEOF, // sizeof
{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)
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
-
scf_vector_t* _continues;
scf_vector_t* _gotos;
scf_vector_t* _labels;
- scf_vector_t* _errors;
scf_vector_t* _ends;
} scf_branch_ops_t;
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;
}
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);
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;
}
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");
}
}
- 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");
}
}
- 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");
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");
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);
}
}
- 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;
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");
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;
}
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);
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;
}
{
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;
}
}
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;
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);
}
// 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;
}
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;
};
// 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.
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;
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;
}
}
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;
}
}
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);
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);
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,
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();
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);
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);
}
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);
// 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);
// 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;
}
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);
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);
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;
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; \
\
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)
return NULL;
}
-
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;
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;
--- /dev/null
+ 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,
+------------------------------------------------------------------------------------------------
+
+
--- /dev/null
+ 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
+------------------------------------------------------------------------------------------------
+
--- /dev/null
+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;
+}
{"return", SCF_LEX_WORD_KEY_RETURN},
{"goto", SCF_LEX_WORD_KEY_GOTO},
- {"error", SCF_LEX_WORD_KEY_ERROR},
{"sizeof", SCF_LEX_WORD_KEY_SIZEOF},
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
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
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;
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)
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);
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;
}
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);
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;
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);
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);
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++) {
.fini_module = _dfa_fini_module_block,
};
-
scf_type_t* current_class;
- scf_dfa_hook_t* hook_end;
-
int nb_lbs;
int nb_rbs;
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;
}
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;
}
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);
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;
}
parse->ast->current_block = (scf_block_t*)t;
- printf("%s(), %d, t: %p\n", __func__, __LINE__, t);
-
return SCF_DFA_NEXT_WORD;
}
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;
}
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;
}
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;
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;
}
--- /dev/null
+#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,
+};
+++ /dev/null
-#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,
-};
-
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)
{
_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;
}
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;
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;
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)
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;
d->current_function->node.define_flag = 1;
fd->parent_block = NULL;
- fd->hook_end = NULL;
d->current_function = NULL;
d->argc = 0;
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;
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);
#include"scf_dfa.h"
+#include"scf_dfa_util.h"
#include"scf_parse.h"
#include"scf_stack.h"
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)
{
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;
}
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;
}
}
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;
{
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;
// last else block
scf_dfa_node_add_child(_else, block);
- scf_loge("\n");
+ scf_logi("\n");
return 0;
}
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;
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);
#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;
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;
}
.init_module = _dfa_init_module_label,
.init_syntax = _dfa_init_syntax_label,
};
-
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)
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;
d->current_function->node.define_flag = 1;
opd->parent_block = NULL;
- opd->hook_end = NULL;
d->current_function = NULL;
d->argc = 0;
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;
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;
&dfa_module_if,
&dfa_module_while,
- &dfa_module_repeat,
+ &dfa_module_do,
&dfa_module_for,
+ &dfa_module_switch,
#if 1
&dfa_module_break,
&dfa_module_goto,
&dfa_module_return,
&dfa_module_label,
- &dfa_module_error,
&dfa_module_async,
#endif
&dfa_module_block,
+++ /dev/null
-#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,
-};
-
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;
{
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;
}
+++ /dev/null
-#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,
-};
-
--- /dev/null
+#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,
+};
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;
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;
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;
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) {
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;
}
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)
{
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;
}
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;
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;
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);
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;
}
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);
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);
{
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) {
return -1;
}
- ast->current_block = prev_block;
+ ast->current_block = tmp;
return 0;
}
}
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)
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)
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;
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;
}
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;
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;
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);
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);
{
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) {
return -1;
}
- ast->current_block = prev_block;
+ ast->current_block = tmp;
return 0;
}
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;
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) {
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");
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;
{
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);
{
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);
{
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) {
{
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) {
{
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);
{
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)) {
}
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)
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);
+++ /dev/null
-
-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;
-}
-
-