koop.cc 4.82 KiB
#include "koop.hh"
using namespace std;
int name_counter = 0;
Value::Value(string instx, string return_v, int num)
    inst = instx;
    return_value = return_v;
    space_num = num;
Value::Value(string instx, string target, string left, string right, int num)
    inst = instx;
    target_reg = target;
    left_reg = left;
    right_reg = right;
    space_num = num;
void Value::Dump(string &s)
    for (int i=0;i<4*space_num;i++)
        s+=" ";
    if (inst == "ret")
        s += (inst+" "+return_value+'\n');
    else
        s += (target_reg+" = "+inst+" "+left_reg+", "+right_reg+'\n');
void BasicBlock::addValue(BlockAST* block)
    //BlockAST* blockAST = dynamic_cast<BlockAST*>(block.get());
    StmtAST* stmt = dynamic_cast<StmtAST*>(block->stmt.get());
    auto return_value = addValue(stmt);
    Values.emplace_back(Value("ret",return_value,space_num + 1));
string BasicBlock::addValue(StmtAST* stmt)
    ExpAST* exp = dynamic_cast<ExpAST*>(stmt->exp.get());
    return addValue(exp);
string BasicBlock::addValue(ExpAST* exp)
    AddExpAST* addexp = dynamic_cast<AddExpAST*>(exp->addexp.get());
    return addValue(addexp);
string BasicBlock::addValue(UnaryExpAST* unaryexp)
    if (unaryexp->type == UnaryExpAST::Type::Primary)
        PrimaryExpAST* primaryexp = dynamic_cast<PrimaryExpAST*>(unaryexp->primary_exp.get());
        return addValue(primaryexp);
    else
        UnaryExpAST* unary_exp = dynamic_cast<UnaryExpAST*>(unaryexp->unary_exp.get());
        string op = unaryexp->unary_op;
        auto res = addValue(unary_exp);
        if (op == "+")
            return res;
        string target = "";
7172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
target = "%" + to_string(reg_id); reg_id++; if (op == "!") Values.emplace_back(Value("eq",target,res,"0",space_num + 1)); else if (op == "-") Values.emplace_back(Value("sub",target,"0",res,space_num + 1)); return target; } } string BasicBlock::addValue(PrimaryExpAST* primaryexp) { if (primaryexp->type == PrimaryExpAST::Type::Exp) { ExpAST* exp = dynamic_cast<ExpAST*>(primaryexp->exp.get()); return addValue(exp); } else { int num = primaryexp->number; return to_string(num); } } string BasicBlock::addValue(AddExpAST* addexp) { if (addexp->type == AddExpAST::Type::NOOP) { MulExpAST* mulexp = dynamic_cast<MulExpAST*>(addexp->mulexp.get()); return addValue(mulexp); } else { AddExpAST* add2exp = dynamic_cast<AddExpAST*>(addexp->addexp.get()); MulExpAST* mulexp = dynamic_cast<MulExpAST*>(addexp->mulexp.get()); string op = addexp->op; auto lhs = addValue(add2exp); auto rhs = addValue(mulexp); string target = ""; target = "%" + to_string(reg_id); reg_id++; if (op == "+") Values.emplace_back(Value("add",target,lhs,rhs,space_num + 1)); else if (op == "-") Values.emplace_back(Value("sub",target,lhs,rhs,space_num + 1)); return target; } } string BasicBlock::addValue(MulExpAST* mulexp) { if (mulexp->type == MulExpAST::Type::NOOP) { UnaryExpAST* unaryexp = dynamic_cast<UnaryExpAST*>(mulexp->unaryexp.get()); return addValue(unaryexp); } else { UnaryExpAST* unaryexp = dynamic_cast<UnaryExpAST*>(mulexp->unaryexp.get()); MulExpAST* mul2exp = dynamic_cast<MulExpAST*>(mulexp->mulexp.get()); string op = mulexp->op;
141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
auto lhs = addValue(mul2exp); auto rhs = addValue(unaryexp); string target = ""; target = "%" + to_string(reg_id); reg_id++; if (op == "*") Values.emplace_back(Value("mul",target,lhs,rhs,space_num + 1)); else if (op == "/") Values.emplace_back(Value("div",target,lhs,rhs,space_num + 1)); else if (op == "%") Values.emplace_back(Value("mod",target,lhs,rhs,space_num + 1)); return target; } } void BasicBlock::Dump(string &s) { for(int i=0;i<space_num*4;i++) s+=" "; s += ("%"+blockname+":"+'\n'); for (auto v:Values) v.Dump(s); cout<<endl; } Func::Func(FuncDefAST* funcdef) { funcname = funcdef->ident; FuncTypeAST* functype = dynamic_cast<FuncTypeAST*>(funcdef->func_type.get()); BlockAST* block = dynamic_cast<BlockAST*>(funcdef->block.get()); if (functype->s == "int") return_type = "i32"; addBlock(block, space_num); } void Func::addBlock(BlockAST* block, int space_num) { BasicBlock b = BasicBlock("entry", space_num + 1); b.addValue(block); blocks.push_back(b); } void Func::Dump(string &s) { for(int i=0;i<space_num*4;i++) s+=" "; s += ("fun @"+funcname+"(): "+return_type+'\n'+"{\n"); for (auto block: blocks) block.Dump(s); s += ("}\n\n"); }