diff --git a/src/ast.cc b/src/ast.cc deleted file mode 100644 index 2836a92875d0e786ae9229bcee5a8e0f1b392dbe..0000000000000000000000000000000000000000 --- a/src/ast.cc +++ /dev/null @@ -1,38 +0,0 @@ -#include "ast.hh" - -void CompUnitAST::Dump() const -{ - std::cout << "CompUnitAST { "; - func_def->Dump(); - std::cout << " }"; -} - -void FuncDefAST::Dump() const -{ - std::cout << "FuncDefAST { "; - func_type->Dump(); - std::cout<<", "<<ident<<", "; - block->Dump(); - std::cout << " }"; -} - -void FuncTypeAST::Dump() const -{ - std::cout << "FuncTypeAST { "; - std::cout<<s; - std::cout << " }"; -} - -void BlockAST::Dump() const -{ - std::cout << "BlockAST { "; - stmt->Dump(); - std::cout << " }"; -} - -void StmtAST::Dump() const -{ - std::cout << "StmtAST { "; - std::cout << number; - std::cout << " }"; -} \ No newline at end of file diff --git a/src/ast.h b/src/ast.h deleted file mode 100644 index 3a1bcaa03180a8c736e2f3539ec2850dd078d507..0000000000000000000000000000000000000000 --- a/src/ast.h +++ /dev/null @@ -1,77 +0,0 @@ -#pragma once -#include <string> -#include <memory> -#include <iostream> - -// 所有 AST 的基类 -class BaseAST { - public: - virtual ~BaseAST() = default; - virtual void Dump() const = 0; -}; - -// CompUnit 是 BaseAST -class CompUnitAST : public BaseAST { - public: - // 用智能指针管ç†å¯¹è±¡ - std::unique_ptr<BaseAST> func_def; - - void Dump() const override { - std::cout << "CompUnitAST { "; - func_def->Dump(); - std::cout << " }"; - } -}; - -// FuncDef 也是 BaseAST -class FuncDefAST : public BaseAST { - public: - std::unique_ptr<BaseAST> func_type; - std::string ident; - std::unique_ptr<BaseAST> block; - - void Dump() const override { - std::cout << "FuncDefAST { "; - func_type->Dump(); - std::cout<<", "<<ident<<", "; - block->Dump(); - std::cout << " }"; - } -}; - -class FuncTypeAST : public BaseAST -{ - public: - std::string s = "int"; - - void Dump() const override { - std::cout << "FuncTypeAST { "; - std::cout<<s; - std::cout << " }"; - } -}; - -class BlockAST : public BaseAST -{ - public: - std::unique_ptr<BaseAST> stmt; - - void Dump() const override { - std::cout << "BlockAST { "; - stmt->Dump(); - std::cout << " }"; - } -}; - -class StmtAST : public BaseAST -{ - public: - int number = 0; - - void Dump() const override { - std::cout << "StmtAST { "; - std::cout << number; - std::cout << " }"; - } -}; - diff --git a/src/ast.hh b/src/ast.hh index 519bde2e92ba88ad518cb26c5c1782c4837a8ddb..f6d5b3b6902cadf4804eef94c7d9dbebdc8605fe 100644 --- a/src/ast.hh +++ b/src/ast.hh @@ -13,7 +13,6 @@ class StmtAST; class BaseAST { public: virtual ~BaseAST() = default; - virtual void Dump() const = 0; }; // CompUnit 是 BaseAST @@ -22,7 +21,6 @@ class CompUnitAST : public BaseAST { // 用智能指针管ç†å¯¹è±¡ std::unique_ptr<BaseAST> func_def; - void Dump() const override; }; // FuncDef 也是 BaseAST @@ -32,7 +30,6 @@ class FuncDefAST : public BaseAST { std::string ident; std::unique_ptr<BaseAST> block; - void Dump() const override; }; class FuncTypeAST : public BaseAST @@ -40,7 +37,6 @@ class FuncTypeAST : public BaseAST public: std::string s = "int"; - void Dump() const override; }; class BlockAST : public BaseAST @@ -48,14 +44,46 @@ class BlockAST : public BaseAST public: std::unique_ptr<BaseAST> stmt; - void Dump() const override; }; class StmtAST : public BaseAST { public: - int number = 0; + std::unique_ptr<BaseAST> exp; - void Dump() const override; }; +class ExpAST : public BaseAST +{ + public: + std::unique_ptr<BaseAST> unaryexp; + +}; + +class UnaryExpAST : public BaseAST +{ + public: + enum class Type { + Primary, + OP + }; + Type type; + std::unique_ptr<BaseAST> primary_exp; + std::string unary_op; + std::unique_ptr<BaseAST> unary_exp; +}; + +class PrimaryExpAST : public BaseAST +{ + public: + enum class Type { + Exp, + Number + }; + Type type; + std::unique_ptr<BaseAST> exp; + int number; +}; + + + diff --git a/src/koop.cc b/src/koop.cc index a3dcce1b76f60a693e5cf9d44500cf1b0d3bda31..f8cde850587e7788f29423644f40237445469ea8 100644 --- a/src/koop.cc +++ b/src/koop.cc @@ -3,59 +3,100 @@ using namespace std; int name_counter = 0; -Value::Value(string x, string y, int num) + +Value::Value(string instx, string return_v, int num) { - inst = x; - return_value = y; + inst = instx; + return_value = return_v; space_num = num; } -Value::Value(string x, int y, int num) +Value::Value(string instx, string target, string left, string right, int num) { - inst = x; - return_value = to_string(y); + inst = instx; + target_reg = target; + left_reg = left; + right_reg = right; space_num = num; } -void Value::Dump() -{ - for (int i=0;i<4*space_num;i++) - cout<<" "; - - cout<<inst<<" "<<return_value<<endl; -} void Value::Dump(string &s) { for (int i=0;i<4*space_num;i++) s+=" "; - - s += (inst+" "+return_value+'\n'); + if (inst == "ret") + s += (inst+" "+return_value+'\n'); + else + s += (target_reg+" = "+inst+" "+left_reg+", "+right_reg+'\n'); } -void BasicBlock::addValue(string x, string y) -{ - Values.emplace_back(Value(x,y,space_num + 1)); -} + void BasicBlock::addValue(BlockAST* block) { //BlockAST* blockAST = dynamic_cast<BlockAST*>(block.get()); StmtAST* stmt = dynamic_cast<StmtAST*>(block->stmt.get()); - Values.emplace_back(Value("ret",stmt->number,space_num + 1)); + auto return_value = addValue(stmt); + Values.emplace_back(Value("ret",return_value,space_num + 1)); } -void BasicBlock::Dump() +string BasicBlock::addValue(StmtAST* stmt) { - for(int i=0;i<space_num*4;i++) - cout<<" "; - cout<<"%"<<blockname<<":"<<endl; + ExpAST* exp = dynamic_cast<ExpAST*>(stmt->exp.get()); + return addValue(exp); +} - for (auto v:Values) - v.Dump(); - cout<<endl; +string BasicBlock::addValue(ExpAST* exp) +{ + UnaryExpAST* unaryexp = dynamic_cast<UnaryExpAST*>(exp->unaryexp.get()); + return addValue(unaryexp); +} + +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 = ""; + 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); + } } + void BasicBlock::Dump(string &s) { for(int i=0;i<space_num*4;i++) @@ -84,16 +125,6 @@ void Func::addBlock(BlockAST* block, int space_num) blocks.push_back(b); } -void Func::Dump() -{ - for(int i=0;i<space_num*4;i++) - cout<<" "; - cout<<"fun @"<<funcname<<"(): "<<return_type<<endl<<"{"<<endl; - - for (auto block: blocks) - block.Dump(); - cout<<"}"<<endl<<endl; -} void Func::Dump(string &s) { diff --git a/src/koop.hh b/src/koop.hh index b4aaf594ba1f7487f580376ec3a4a6ee8d7326ad..2a9e2d1402693aaaffcd9890870fde7130c0f641 100644 --- a/src/koop.hh +++ b/src/koop.hh @@ -8,14 +8,16 @@ extern int name_counter; class Value { public: + string target_reg; + string left_reg; + string right_reg; //koopIR 里在ç‰å·å³è¾¹çš„第一个和第二个寄å˜å™¨ string inst; string return_value; int space_num = 0; - Value(string x, string y, int num = 0); - Value(string x, int y, int num = 0); + Value(string instx, string return_v, int num = 0); + Value(string instx, string target, string left, string right, int num=0); - void Dump(); void Dump(string &s); virtual ~Value() = default; @@ -26,6 +28,7 @@ class BasicBlock public: string blockname; vector<Value> Values; + int reg_id = 0; int space_num = 0; BasicBlock(string s, int num = 0):blockname(s), space_num(num) {}; @@ -36,9 +39,11 @@ class BasicBlock space_num = num; } - void addValue(string x, string y); void addValue(BlockAST* block); - void Dump(); + string addValue(StmtAST* stmt); + string addValue(ExpAST* exp); + string addValue(UnaryExpAST* unaryexp); + string addValue(PrimaryExpAST* primaryexp); void Dump(string &s); virtual ~BasicBlock() = default; @@ -55,7 +60,6 @@ class Func Func(FuncDefAST* funcdef); void addBlock(BlockAST* block, int space_num); - void Dump(); void Dump(string &s); virtual ~Func() = default; diff --git a/src/main.cpp b/src/main.cpp index fc8431fab088f913f37c6ff607f6ee23b4b6fcfe..5f6c464c0c6530450e7a2f32dac043d8fd075722 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -32,12 +32,13 @@ int main(int argc, const char *argv[]) { // 调用 parser 函数, parser 函数会进一æ¥è°ƒç”¨ lexer è§£æžè¾“入文件的 unique_ptr<BaseAST> ast; auto ret = yyparse(ast); - assert(!ret); + assert(!ret); + // 输出解æžå¾—到的 AST, 其实就是个å—符串 CompUnitAST* aast = dynamic_cast<CompUnitAST*>(ast.get()); - FuncDefAST* ga = dynamic_cast<FuncDefAST*>(aast->func_def.get()); - Func func = Func(ga); + FuncDefAST* funcast = dynamic_cast<FuncDefAST*>(aast->func_def.get()); + Func func = Func(funcast); string koop_string = ""; func.Dump(koop_string); @@ -61,5 +62,6 @@ int main(int argc, const char *argv[]) { // 注æ„, raw program 䏿‰€æœ‰çš„æŒ‡é’ˆæŒ‡å‘的内å˜å‡ä¸º raw program builder çš„å†…å˜ // 所以ä¸è¦åœ¨ raw program 处ç†å®Œæ¯•之å‰é‡Šæ”¾ builder koopa_delete_raw_program_builder(builder); + } diff --git a/src/raw.cc b/src/raw.cc index 1508dd152636cbda48e5eebbc1368c4dd3d97c0b..bd5f5df39db2b90a67654ae447b7869973c99ae9 100644 --- a/src/raw.cc +++ b/src/raw.cc @@ -1,9 +1,11 @@ #include "raw.hh" #include <iostream> #include <cassert> -#include <cstring> +#include <map> using namespace std; +map<koopa_raw_value_t,string> rstack; +int reg_id = 0; // 访问 raw program void Visit(const koopa_raw_program_t &program) { // æ‰§è¡Œä¸€äº›å…¶ä»–çš„å¿…è¦æ“作 @@ -48,8 +50,7 @@ void Visit(const koopa_raw_function_t &func) { cout<<func->name[i]; cout<<":"<<endl; // è®¿é—®æ‰€æœ‰åŸºæœ¬å— - for (size_t i = 0; i < func->bbs.len; ++i) - Visit(func->bbs); + Visit(func->bbs); } @@ -58,37 +59,90 @@ void Visit(const koopa_raw_basic_block_t &bb) { // æ‰§è¡Œä¸€äº›å…¶ä»–çš„å¿…è¦æ“作 // ... // 访问所有指令 - for (size_t i = 0; i < bb->insts.len; ++i) - Visit(bb->insts); + Visit(bb->insts); } // 访问指令 -void Visit(const koopa_raw_value_t &value) { +string Visit(const koopa_raw_value_t &value) { // æ ¹æ®æŒ‡ä»¤ç±»åž‹åˆ¤æ–åŽç»éœ€è¦å¦‚何访问 const auto &kind = value->kind; + string toreg = ""; + if (rstack.find(value) != rstack.end()) + return rstack[value]; + + switch (kind.tag) { case KOOPA_RVT_RETURN: // 访问 return 指令 - Visit(kind.data.ret); + toreg = Visit(kind.data.ret); break; case KOOPA_RVT_INTEGER: // 访问 integer 指令 - Visit(kind.data.integer); + toreg = Visit(kind.data.integer); + break; + case KOOPA_RVT_BINARY: + toreg = Visit(kind.data.binary); break; default: // 其他类型暂时é‡ä¸åˆ° assert(false); } + rstack[value] = toreg; + return toreg; } -void Visit(const koopa_raw_return_t &ret) +string Visit(const koopa_raw_return_t &ret) { - cout<<" "<<"li a0, "; - Visit(ret.value); + cout<<" "<<"mv a0, "; + auto reg = Visit(ret.value); + cout<<reg<<endl; cout<<" "<<"ret"<<endl; + + return ""; } -void Visit(const koopa_raw_integer_t &value) +string Visit(const koopa_raw_integer_t &value) { - cout<<value.value<<endl; + + if (value.value == 0) + return "x0"; + cout<<" "; + auto treg = "t" + to_string(reg_id); + reg_id++; + + cout<<"li "<<treg<<", "<<value.value<<endl; + return treg; +} + +string Visit(const koopa_raw_binary_t &binary) +{ + + auto lreg = Visit(binary.lhs); + auto rreg = Visit(binary.rhs); + string treg = ""; + + cout<<" "; + switch (binary.op) + { + case KOOPA_RBO_SUB: + treg = "t" + to_string(reg_id); + reg_id++; + cout<<"sub "; + cout<<treg<<", x0, "; + cout<<rreg<<endl; + break; + case KOOPA_RBO_EQ: + cout<<"xor "; + cout<<lreg<<", "<<lreg<<", x0"<<endl; + + cout<<" "; + cout<<"seqz "; + cout<<lreg<<", "<<lreg<<endl; + treg = lreg; + break; + default: + break; + } + + return treg; } diff --git a/src/raw.hh b/src/raw.hh index 806c849077aaad3ce51ab79422c6dc862d5123e5..5cc74cb649b2d86a781008f91c8de6e3278d2c6e 100644 --- a/src/raw.hh +++ b/src/raw.hh @@ -1,9 +1,13 @@ #include "koopa.h" +#include <cstring> +#include <string> void Visit(const koopa_raw_program_t &program); void Visit(const koopa_raw_slice_t &slice); void Visit(const koopa_raw_function_t &func); void Visit(const koopa_raw_basic_block_t &bb); -void Visit(const koopa_raw_value_t &value); -void Visit(const koopa_raw_return_t &ret); -void Visit(const koopa_raw_integer_t &value); +std::string Visit(const koopa_raw_value_t &value); +std::string Visit(const koopa_raw_return_t &ret); +std::string Visit(const koopa_raw_integer_t &value); +std::string Visit(const koopa_raw_binary_t &binary); + diff --git a/src/sysy.l b/src/sysy.l index 5930ee90a318d7ee52020f49329376d1dc26b6bd..af0726c1f9d9961f281160034fb052f067c34a67 100644 --- a/src/sysy.l +++ b/src/sysy.l @@ -6,7 +6,7 @@ #include <cstdlib> #include <string> -#include "ast.h" +#include "ast.hh" // å› ä¸º Flex 会用到 Bison ä¸å…³äºŽ token 的定义 // æ‰€ä»¥éœ€è¦ include Bison 生æˆçš„头文件 @@ -45,6 +45,10 @@ Hexadecimal 0[xX][0-9a-fA-F]+ {Octal} { yylval.int_val = strtol(yytext, nullptr, 0); return INT_CONST; } {Hexadecimal} { yylval.int_val = strtol(yytext, nullptr, 0); return INT_CONST; } +"+" { yylval.str_val = new string(yytext); return UNARYOP; } +"-" { yylval.str_val = new string(yytext); return UNARYOP; } +"!" { yylval.str_val = new string(yytext); return UNARYOP; } + . { return yytext[0]; } %% diff --git a/src/sysy.y b/src/sysy.y index edce519a7c91d0825813ceace040a9f50c064379..3cb660462d6f2ed6725868222fb410a2bda6ca4f 100644 --- a/src/sysy.y +++ b/src/sysy.y @@ -8,7 +8,7 @@ #include <iostream> #include <memory> #include <string> -#include "ast.h" +#include "ast.hh" // 声明 lexer 函数和错误处ç†å‡½æ•° int yylex(); @@ -39,9 +39,10 @@ using namespace std; %token INT RETURN %token <str_val> IDENT %token <int_val> INT_CONST +%token <str_val> UNARYOP // éžç»ˆç»“符的类型定义 -%type <ast_val> FuncDef FuncType Block Stmt +%type <ast_val> FuncDef FuncType Block Stmt Exp UnaryExp PrimaryExp %type <int_val> Number %% @@ -97,13 +98,52 @@ Block ; Stmt - : RETURN Number ';' { + : RETURN Exp ';' { auto ast = new StmtAST(); - ast->number = *make_unique<int>($2); + ast->exp = unique_ptr<BaseAST>($2); $$ = ast; } ; +Exp + : UnaryExp { + auto ast = new ExpAST(); + ast->unaryexp = unique_ptr<BaseAST>($1); + $$ = ast; + } + +UnaryExp + : PrimaryExp { + auto ast = new UnaryExpAST(); + ast->type = UnaryExpAST::Type::Primary; + ast->primary_exp = unique_ptr<BaseAST>($1); + $$ = ast; + } + | UNARYOP UnaryExp { + auto ast = new UnaryExpAST(); + ast->type = UnaryExpAST::Type::OP; + ast->unary_op = *unique_ptr<string> ($1); + ast->unary_exp = unique_ptr<BaseAST>($2); + $$ = ast; + } + ; + +PrimaryExp + : '(' Exp ')' { + auto ast = new PrimaryExpAST(); + ast->type = PrimaryExpAST::Type::Exp; + ast->exp = unique_ptr<BaseAST>($2); + $$ = ast; + } + | Number { + auto ast = new PrimaryExpAST(); + ast->type = PrimaryExpAST::Type::Number; + ast->number = *make_unique<int>($1); + $$ = ast; + } + ; + + Number : INT_CONST { $$ = $1;