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

📄 optimize.cc

📁 PL/0源码
💻 CC
字号:
//////////////////////////////////////////////////////////////////////////////////  optimize.cc -- procedures for AST optimization////  The main entry point in this file is optimize_syntax_tree.//  It should do all sorts of machine-independent optimizations.////  At the moment, all it does is evaluate constant expressions//  (unsafely: there's no check for overflow!) and detect subroutines//  with no local variables (makes stack allocation easier).//#include "tokens.h"#include "symtab.h"#include "attributes.h"#include "optimize.h"bool evaluate_consts = true;static se_procedure_t * current_procedure = NULL;//////////////////////////////////////////////////////////////////////////////////  Every node a syntax tree must implement the optimize member function.//  Optimize should perform any optimizations that in can (including calling//  optimize for each of its children) and should then return either a pointer//  to itself or to another node which will replace it.  We use this//  replacement options in cases such as a binary operation on two constants//  which replaces itself with a single constant.//syntax_tree_t *syntax_tree_t::optimize(void){    return this;}syntax_tree_t *st_token_t::optimize(void){    return this;}syntax_tree_t *st_identifier_t::optimize(void){    if (symbol_entry == input_symbol && current_procedure != NULL)        current_procedure->not_leaf();    if (se_constant_t *con = dynamic_cast<se_constant_t *>(symbol_entry)) {        // cast will fail (return NULL) if we're not a constant        st_number_t *n = new st_number_t(attributes, con->get_value());        delete this;        return n;    }    return this;}syntax_tree_t *st_number_t::optimize(void){    return this;}syntax_tree_t *st_operator_t::optimize(void){    return this;}syntax_tree_t *st_unary_op_t::optimize(void){    st_number_t *       number;    operand = optimize_syntax_tree(operand);    if (evaluate_consts && (number = dynamic_cast<st_number_t *>(operand))) {        // cast will fail (return NULL) if operand isn't a constant        // Replace ourselves with the NUMBER constant.        st_number_t *   n = NULL;        int             value;        token_attrib_t  t = op->get_attributes();        switch (t.get_minor()) {        case MIN_MINUS:            value = -number->get_value();            n = new st_number_t(t, value);            break;        case MIN_ODD:            value = number->get_value() & 1;            n = new st_number_t(t, value);            break;        }        if (n) {            delete this;            return n;        }    }    return this;}syntax_tree_t *st_binary_op_t::optimize(void){    st_number_t *       left_number;    st_number_t *       right_number;    left_operand = optimize_syntax_tree(left_operand);    right_operand = optimize_syntax_tree(right_operand);    if (evaluate_consts        && (left_number = dynamic_cast<st_number_t *>(left_operand))        && (right_number = dynamic_cast<st_number_t *>(right_operand))) {        // casts may fail (return NULL) if operands are not constants        // Replace ourselves with the NUMBER constant.        st_number_t *   n = NULL;        int             value;        token_attrib_t  t = op->get_attributes();        switch (t.get_minor()) {        case MIN_PLUS:            value = left_number->get_value() + right_number->get_value();            n = new st_number_t(t, value);            break;        case MIN_MINUS:            value = left_number->get_value() - right_number->get_value();            n = new st_number_t(t, value);            break;        case MIN_TIMES:            value = left_number->get_value() * right_number->get_value();            n = new st_number_t(t, value);            break;        case MIN_SLASH:            if (right_number->get_value() == 0)                issue_error (location, "Division by zero");            else            {                value = left_number->get_value() / right_number->get_value();                n = new st_number_t(t, value);            }            break;        case MIN_EQ:            value = left_number->get_value() == right_number->get_value();            n = new st_number_t(t, value);            break;        case MIN_NE:            value = left_number->get_value() != right_number->get_value();            n = new st_number_t(t, value);            break;        case MIN_LT:            value = left_number->get_value() < right_number->get_value();            n = new st_number_t(t, value);            break;        case MIN_LE:            value = left_number->get_value() <= right_number->get_value();            n = new st_number_t(t, value);            break;        case MIN_GT:            value = left_number->get_value() > right_number->get_value();            n = new st_number_t(t, value);            break;        case MIN_GE:            value = left_number->get_value() >= right_number->get_value();            n = new st_number_t(t, value);            break;        default: break;        } //case        if (n != NULL) {            delete this;            return n;        }    }    return this;}syntax_tree_t *st_statement_t::optimize(void){    next_statement = optimize_syntax_tree(next_statement);    return this;}syntax_tree_t *st_assignment_t::optimize(void){    left_side =        dynamic_cast<st_identifier_t *>(optimize_syntax_tree(left_side));        // cast should never fail    right_side = optimize_syntax_tree(right_side);    if (left_side->get_symbol() == output_symbol && current_procedure != NULL)        current_procedure->not_leaf();    next_statement = optimize_syntax_tree(next_statement);    return this;}syntax_tree_t *st_while_t::optimize(void){    condition = optimize_syntax_tree(condition);    body = optimize_syntax_tree(body);    next_statement = optimize_syntax_tree(next_statement);    return this;}syntax_tree_t *st_if_t::optimize(void){    condition = optimize_syntax_tree(condition);    body = optimize_syntax_tree(body);    next_statement = optimize_syntax_tree(next_statement);    return this;}syntax_tree_t *st_call_t::optimize(void){    procedure =        dynamic_cast<st_identifier_t *>(optimize_syntax_tree(procedure));        // cast should never fail    if (current_procedure != NULL)        current_procedure->not_leaf();    next_statement = optimize_syntax_tree(next_statement);    return this;}syntax_tree_t *st_declaration_t::optimize(void){    next_declaration = optimize_syntax_tree(next_declaration);    return this;}syntax_tree_t *st_constant_t::optimize(void){    value = dynamic_cast<st_number_t *>(optimize_syntax_tree(value));        // cast should never fail    next_declaration = optimize_syntax_tree(next_declaration);    return this;}syntax_tree_t *st_variable_t::optimize(void){    if (current_procedure != NULL)        current_procedure->set_locals();    next_declaration = optimize_syntax_tree(next_declaration);    return this;}syntax_tree_t *st_procedure_t::optimize(void){    se_procedure_t *    oldProc = current_procedure;    current_procedure =        dynamic_cast<se_procedure_t *>(identifier->get_symbol());        // cast should never fail    block = dynamic_cast<st_block_t *>(optimize_syntax_tree(block));        // cast should never fail    current_procedure = oldProc;    next_declaration = optimize_syntax_tree(next_declaration);    return this;}syntax_tree_t *st_block_t::optimize(void){    declarations = optimize_syntax_tree(declarations);    body = optimize_syntax_tree(body);    return this;}//////////  Optimize the abstract syntax tree//syntax_tree_t *optimize_syntax_tree(syntax_tree_t * node){    if (node != NULL)        return node->optimize();    return node;}// End of File

⌨️ 快捷键说明

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