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;