⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.cc

📁 c到DHL的转换工具
💻 CC
📖 第 1 页 / 共 2 页
字号:
        start_bj = (in_bj *)(start_instr);        delete jumpto_info;        tree_node *jumpto_lab_node = jumpto_lab_instr->owner();        tree_node_list_e *follow_back = jumpto_lab_node->list_e()->prev();        assert(follow_back != NULL);        while (follow_back->contents->is_instr())          {            tree_instr *back_tree_instr =                    (tree_instr *)(follow_back->contents);            instruction *back_instr = back_tree_instr->instr();            if (back_instr->opcode() != io_mrk)                break;            follow_back = follow_back->prev();            assert(follow_back != NULL);            destroy_node(back_tree_instr);          }        assert(follow_back->contents->is_instr());        tree_instr *goto_node = (tree_instr *)(follow_back->contents);        instruction *goto_instr = goto_node->instr();        assert(goto_instr->opcode() == io_jmp);        in_bj *goto_bj = (in_bj *)(goto_instr);        end_label_instr = split_out(end_label_instr, goto_bj);        end_node = end_label_instr->owner();        move_nodes(jumpto_lab_node, end_node, new_else);        destroy_node(goto_node);        destroy_node(jumpto_lab_node);        force_same_list(start_bj->owner(), end_node);      }    else      {        start_bj = (in_bj *)(the_info->start_instr);        end_label_instr = split_out(end_label_instr, start_bj);        jumpto_sym = start_bj->target();        end_node = end_label_instr->owner();      }    tree_node *start_node = start_bj->owner();    move_nodes(start_node, end_node, new_then);    destroy_node(end_node);    tree_if *new_if = new tree_if(jumpto_sym, new_header, new_then, new_else);    tree_node_list_e *start_e = start_node->list_e();    parent_list->insert_after(new_if, start_e);    parent_list->remove(start_e);    new_header->append(start_e);    remove_label_info(new_then);    remove_label_info(new_else);  }static void build_do(arc_info *the_info)  {    assert(!the_info->broken);    assert(the_info->start_instr->opcode() == io_lab);    assert(the_info->end_instr != NULL);    assert((the_info->end_instr->opcode() == io_btrue) ||           (the_info->end_instr->opcode() == io_bfalse) ||           (the_info->end_instr->opcode() == io_jmp));    in_lab *top_label_instr = (in_lab *)(the_info->start_instr);    in_bj *bottom_branch = (in_bj *)(the_info->end_instr);    tree_node *bottom_node = bottom_branch->owner();    top_label_instr = split_out(top_label_instr, bottom_branch);    tree_node *top_node = top_label_instr->owner();    tree_node_list *parent_list = top_node->parent();    label_sym *top_label_sym = top_label_instr->label();    assert(bottom_branch->target() == top_label_sym);    base_symtab *base_scope = top_node->scope();    assert(base_scope->is_block());    block_symtab *block_scope = (block_symtab *)base_scope;    tree_node_list_e *new_top_e = top_node->list_e()->next();    assert(new_top_e != NULL);    destroy_node(top_node);    top_node = new_top_e->contents;    tree_node_list *new_body = new tree_node_list;    tree_node_list *new_test = new tree_node_list;    label_sym *continue_lab = block_scope->new_unique_label();    label_sym *break_lab = block_scope->new_unique_label();    tree_loop *new_loop =            new tree_loop(new_body, new_test, continue_lab, break_lab,                          top_label_sym);    parent_list->insert_before(new_loop, new_top_e);    while (top_node != bottom_node)      {        tree_node_list_e *this_e = top_node->list_e();        tree_node_list_e *next_e = this_e->next();        assert(next_e != NULL);        parent_list->remove(this_e);        new_body->append(this_e);        top_node = next_e->contents;      }    tree_node_list_e *bottom_e = bottom_node->list_e();    parent_list->remove(bottom_e);    new_test->append(bottom_e);    remove_label_info(new_body);  }static in_lab *split_out(in_lab *target, in_bj *focus)  {    label_sym *lab_sym = target->label();    assert(lab_sym == focus->target());    force_same_list(target->owner(), focus->owner());    label_info *lab_info = get_lab_info(lab_sym);    if (lab_info->backward_jumps.count() + lab_info->forward_jumps.count() ==        1)      {        delete lab_info;        return target;      }    tree_node *target_node = target->owner();    tree_node_list *parent_list = target_node->parent();    base_symtab *base_scope = target_node->scope();    assert(base_scope->is_block());    block_symtab *block_scope = (block_symtab *)base_scope;    label_sym *new_lab_sym = block_scope->new_unique_label(lab_sym->name());    focus->set_target(new_lab_sym);    in_lab *new_target = new in_lab(new_lab_sym);    tree_instr *new_target_node = new tree_instr(new_target);    if ((lab_info->forward_jumps.is_empty() &&         (lab_info->backward_jumps.tail()->contents == focus)) ||        ((!lab_info->forward_jumps.is_empty()) &&         (lab_info->forward_jumps.tail()->contents == focus)))      {        if (lab_info->forward_jumps.is_empty())          {            instruction_list_e *last_e = lab_info->backward_jumps.tail();            lab_info->backward_jumps.remove(last_e);            delete last_e;          }        else          {            instruction_list_e *last_e = lab_info->forward_jumps.tail();            lab_info->forward_jumps.remove(last_e);            delete last_e;          }        parent_list->insert_before(new_target_node, target_node->list_e());        return new_target;      }    if ((lab_info->backward_jumps.is_empty() &&         (lab_info->forward_jumps.head()->contents == focus)) ||        ((!lab_info->backward_jumps.is_empty()) &&         (lab_info->backward_jumps.head()->contents == focus)))      {        if (lab_info->backward_jumps.is_empty())            lab_info->forward_jumps.pop();        else            lab_info->backward_jumps.pop();        parent_list->insert_after(new_target_node, target_node->list_e());        return new_target;      }    label_sym *new_inner_sym = block_scope->new_unique_label(lab_sym->name());    in_lab *new_inner_target = new in_lab(new_inner_sym);    tree_instr *new_inner_node = new tree_instr(new_inner_target);    instruction_list_e *follow_forward = lab_info->forward_jumps.head();    while (follow_forward != NULL)      {        if (follow_forward->contents == focus)          {            parent_list->insert_before(new_target_node, target_node->list_e());            parent_list->insert_before(new_inner_node,                                       new_target_node->list_e());            create_info_for_new_lab_instr(new_inner_target);            rename_inners(&(lab_info->forward_jumps), follow_forward->next(),                          NULL, new_inner_sym, lab_sym);            lab_info->forward_jumps.remove(follow_forward);            delete follow_forward;            return new_target;          }        follow_forward = follow_forward->next();      }    parent_list->insert_after(new_target_node, target_node->list_e());    parent_list->insert_after(new_inner_node, new_target_node->list_e());    create_info_for_new_lab_instr(new_inner_target);    rename_inners(&(lab_info->backward_jumps), lab_info->backward_jumps.head(),                  focus, new_inner_sym, lab_sym);    instruction_list_e *follow_backward = lab_info->backward_jumps.head();    while (TRUE)      {        assert(follow_backward != NULL);        if (follow_backward->contents == focus)            break;        follow_backward = follow_backward->next();      }    lab_info->backward_jumps.remove(follow_backward);    delete follow_backward;    return new_target;  }static void rename_inners(instruction_list *i_list, instruction_list_e *start,                          instruction *end, label_sym *new_label,                          label_sym *old_label)  {    label_info *inner_lab_info = get_lab_info(new_label);    instruction_list_e *follow = start;    do      {        instruction *this_instr = follow->contents;        if (this_instr == end)            return;        switch (this_instr->opcode())          {            case io_btrue:            case io_bfalse:            case io_jmp:              {                in_bj *the_bj = (in_bj *)this_instr;                assert(the_bj->target() == old_label);                the_bj->set_target(new_label);                break;              }            case io_mbr:              {                in_mbr *the_mbr = (in_mbr *)this_instr;                if (the_mbr->default_lab() == old_label)                  {                    the_mbr->set_default_lab(new_label);                  }                else                  {                    unsigned num_labs = the_mbr->num_labs();                    unsigned lab_num;                    for (lab_num = 0; lab_num < num_labs; ++lab_num)                      {                        if (the_mbr->label(lab_num) == old_label)                          {                            the_mbr->set_label(lab_num, new_label);                            break;                          }                      }                    assert(lab_num < num_labs);                  }                break;              }            default:                assert(FALSE);          }        instruction_list_e *next_e = follow->next();        i_list->remove(follow);        inner_lab_info->backward_jumps.append(follow);        follow = next_e;      } while (follow != NULL);  }static void move_nodes(tree_node *before, tree_node *after,                       tree_node_list *new_list)  {    tree_node_list_e *follow = before->list_e()->next();    tree_node_list *old_list = before->parent();    while (TRUE)      {        assert(follow != NULL);        if (follow->contents == after)            return;        tree_node_list_e *next_e = follow->next();        old_list->remove(follow);        new_list->append(follow);        follow = next_e;      }  }static void destroy_node(tree_node *old_node)  {    tree_node_list *parent_list = old_node->parent();    tree_node_list_e *old_e = old_node->list_e();    parent_list->remove(old_e);    delete old_e;    delete old_node;  }static boolean is_if_else_boundary(in_bj *the_bj, arc_info_list *arc_stack)  {    if (is_backward_branch(the_bj))        return FALSE;    if (the_bj->opcode() != io_jmp)        return FALSE;    arc_info_list_e *stack_head = arc_stack->head();    if (stack_head == NULL)        return FALSE;    if (stack_head->contents.broken)        return FALSE;    instruction *end_instr = stack_head->contents.end_instr;    if ((end_instr == NULL) || (end_instr->opcode() != io_lab))        return FALSE;    in_lab *else_lab_instr = (in_lab *)end_instr;    label_info *else_lab_info = get_lab_info(else_lab_instr->label());    if ((!else_lab_info->backward_jumps.is_empty()) ||        (else_lab_info->forward_jumps.count() != 1))      {        return FALSE;      }    tree_node_list_e *end_list_e = end_instr->owner()->list_e();    tree_node_list_e *follow_e = the_bj->owner()->list_e()->next();    while (follow_e != end_list_e)      {        if (follow_e == NULL)            return FALSE;        tree_node *this_node = follow_e->contents;        if (!this_node->is_instr())            return FALSE;        tree_instr *this_tree_instr = (tree_instr *)this_node;        instruction *this_instr = this_tree_instr->instr();        if (this_instr->opcode() != io_mrk)            return FALSE;        follow_e = follow_e->next();      }    return TRUE;  }/* *  When we are looking at control flow, we ignore the beginnings and *  endings of block scopes, so node1 and node2 might be in different *  lists.  However, having one in the body of a tree_for, for *  example, while the other is not, cannot happen.  Another way to *  put the same statement is that by dismantling only tree_block *  nodes we are guaranteed to be able to get the two nodes on the *  same list.  So that's what we do here -- we dismantle tree_block *  nodes as necessary. */static void force_same_list(tree_node *node1, tree_node *node2)  {    tree_node_list *parent1 = node1->parent();    tree_node_list *parent2 = node2->parent();    if (parent1 == parent2)        return;    assert(parent1 != NULL);    assert(parent2 != NULL);    tree_node *grandparent1 = parent1->parent();    tree_node *grandparent2 = parent2->parent();    assert(grandparent1 != NULL);    assert(grandparent2 != NULL);    if (!grandparent1->is_block() || grandparent1->is_proc())      {        while (node2->parent() != parent1)          {            tree_node_list *p2 = node2->parent();            assert(p2 != NULL);            tree_node *gp2 = p2->parent();            assert(gp2 != NULL);            assert(gp2->is_block() && !gp2->is_proc());            dismantle(gp2);          }      }    else if (!grandparent2->is_block() || grandparent2->is_proc())      {        while (node1->parent() != parent2)          {            tree_node_list *p1 = node1->parent();            assert(p1 != NULL);            tree_node *gp1 = p1->parent();            assert(gp1 != NULL);            assert(gp1->is_block() && !gp1->is_proc());            dismantle(gp1);          }      }    else      {        tree_block *gptb1 = (tree_block *)grandparent1;        tree_block *gptb2 = (tree_block *)grandparent2;        base_symtab *nearest_symtab =                common_symtab(gptb1->symtab(), gptb2->symtab());        assert(nearest_symtab->is_block());        block_symtab *nearest_block_symtab = (block_symtab *)nearest_symtab;        tree_block *nearest_block = nearest_block_symtab->block();        tree_node_list *target_list = nearest_block->body();        while (node1->parent() != target_list)          {            tree_node_list *p1 = node1->parent();            assert(p1 != NULL);            tree_node *gp1 = p1->parent();            assert(gp1 != NULL);            assert(gp1->is_block() && !gp1->is_proc());            dismantle(gp1);          }        while (node2->parent() != target_list)          {            tree_node_list *p2 = node2->parent();            assert(p2 != NULL);            tree_node *gp2 = p2->parent();            assert(gp2 != NULL);            assert(gp2->is_block() && !gp2->is_proc());            dismantle(gp2);          }      }  }/*----------------------------------------------------------------------*    End Private Function Implementations *----------------------------------------------------------------------*/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -