diff --git a/src/ast.rs b/src/ast.rs
index ab94427e471898fc233a2268e3b9ed0f3cfad7b4..b56d136e09385a31dfd2184c700a82b0c36fb98f 100644
--- a/src/ast.rs
+++ b/src/ast.rs
@@ -5,14 +5,18 @@ pub use stmt::{*};
 pub use exp::{*};
 pub use decl::{*};
 // AST for CompUnit
-/// CompUnit  ::= FuncDef;
+/// CompUnit ::= [CompUnit] (Decl | FuncDef);
 #[derive(Debug)]
 pub struct CompUnit {
-    pub func_def: Vec<FuncDef>,
+    pub comp_defs: Vec<CompDef>,
 }
 
 
-
+#[derive(Debug)]
+pub enum CompDef {
+    FuncDef(FuncDef),
+    Decl(Decl)
+}
 
 /// FuncDef   ::= FuncType IDENT "(" [FuncFParams] ")" Block;
 
diff --git a/src/codegen/asmwriter.rs b/src/codegen/asmwriter.rs
index 1021b65679773d5f8029ed53e01d93fa2a157cf1..48c6dc6303f48d818ff9bad14e0c39474d5bb438 100644
--- a/src/codegen/asmwriter.rs
+++ b/src/codegen/asmwriter.rs
@@ -66,6 +66,12 @@ impl AsmWriter {
     }
 
     pub fn load(&self, f: &mut File, context: &mut ProgramContext, value : &Value, tmp: &str) -> CResult<()> {
+        if let Some(v) = context.search_global_var(value) {
+            writeln!(f, "{SPACE}la {}, {}", tmp, v);
+            writeln!(f, "{SPACE}lw {}, 0({})", tmp, tmp);
+            return Ok(());
+        }
+        
         match context.get_value_data(value).kind() {
             ValueKind::Integer(v) => {
                 writeln!(f,"{SPACE}li {}, {}", tmp, v.value())?;
@@ -85,6 +91,11 @@ impl AsmWriter {
         Ok(())
     }
     pub fn store(&self, f: &mut File, context: &mut ProgramContext, value : &Value, tmp: &str) -> CResult<()> {
+        if let Some(v) = context.search_global_var(value) {
+            writeln!(f, "la t3, {}",  v);
+            writeln!(f, "sw {}, 0(t3)", tmp);
+            return Ok(());
+        }
         let pos = context.get_value_position(value)?;
         match pos {
             FuncVar::Stack(p) => {
diff --git a/src/codegen/context.rs b/src/codegen/context.rs
index ec883445967b8a65abe3cc1ef7c7490ea657a8b2..2f49d5a4cda81ed6aea652accb8e73bdb33e8f7d 100644
--- a/src/codegen/context.rs
+++ b/src/codegen/context.rs
@@ -1,3 +1,5 @@
+use std::collections::HashMap;
+
 use koopa::ir::{Program, BasicBlock, Value, entities::ValueData, Function};
 use super::{func::{FunctionHandler,FuncVar}, CResult};
 
@@ -8,9 +10,10 @@ macro_rules! function_handler {
     };
 }
 pub struct ProgramContext<'p> {
-    program: &'p Program,
+    pub program: &'p Program,
     pub cur_func : Option<FunctionHandler>,
     pub func : Option<Function>,
+    pub global_var : HashMap<Value, String>,
     function_cnt : usize,
 }
 
@@ -21,6 +24,7 @@ impl<'p> ProgramContext<'p> {
             program, 
             cur_func: None,
             func : None,
+            global_var : HashMap::new(),
             function_cnt : 0
         }
     }
@@ -28,6 +32,14 @@ impl<'p> ProgramContext<'p> {
         self.program
     }
 
+    pub fn add_global_var(&mut self, value : Value, name: &str) {
+        self.global_var.insert(value, name.into());
+    }
+    
+    pub fn search_global_var(&mut self, value: &Value) -> Option<&str> {
+        self.global_var.get(value).map(|x| x.as_str())
+    }
+
     /// get function handler
     pub fn get_func_handler(&'p mut self) -> Option<&mut FunctionHandler> {
         self.cur_func.as_mut()
diff --git a/src/codegen/gen.rs b/src/codegen/gen.rs
index 2f4621b6ebd5460aaa33a117de7d1ac551ca787f..42a70f5675190b296818f5ba45cc283212de30c7 100644
--- a/src/codegen/gen.rs
+++ b/src/codegen/gen.rs
@@ -8,6 +8,7 @@ use super::{CResult};
 use super::context::ProgramContext;
 use super::func::FunctionHandler;
 use std::fs::File;
+use std::io::Write;
 use std::cmp;
 
 // A unified trait for all the memory structure in Program
@@ -22,8 +23,17 @@ impl<'p> GenerateAsm<'p> for Program {
     type Out = ();
 
     fn generate_asm(&self, f : &'p mut File, context : &'p mut ProgramContext) -> CResult<Self::Out> {
-        
-
+        // generate global allocation
+        for &value in self.inst_layout() {
+            let data = self.borrow_value(value);
+            let name = &data.name().as_ref().unwrap()[1..];
+            context.add_global_var(value, name);
+            writeln!(f, "  .data")?;
+            writeln!(f, "  .globl {}",name)?;
+            writeln!(f, "{}:", name)?;
+            data.generate_asm(f, context, &value)?;
+            writeln!(f)?;
+        }
         // generate function
         for &func in self.func_layout() {
             context.func = Some(func);
diff --git a/src/codegen/gen/valuegen.rs b/src/codegen/gen/valuegen.rs
index 07f71480be7285405a89accb3e75f162470c2571..32deff865a57011688ecfd4034c4cd161e39215d 100644
--- a/src/codegen/gen/valuegen.rs
+++ b/src/codegen/gen/valuegen.rs
@@ -9,27 +9,9 @@ use crate::codegen::CResult;
 #[allow(unused_imports)]
 use super::GenerateAsm;
 use std::fs::File;
+use std::io::Write;
 
 
-
-/*
-impl GenerateAsm for Return {
-    type Out = ();
-    fn generate_asm(&self, f : &mut File, handler : &mut ProgramContext) -> crate::codegen::Result<Self::Out> {
-        match self.value() {
-            Some(v) => {
-
-                writeln!(f,"  li a0, {}", 0)?;
-            }
-            None => ()
-        };
-        
-        writeln!(f,"  ret")?;
-        Ok(())
-    }
-}
-*/
-
 pub trait GenerateAsmValue<'p> {
     type Out;
     fn generate_asm(&self, f : &'p mut File, context : &'p mut ProgramContext, value : &Value) -> CResult<Self::Out>;
@@ -45,6 +27,7 @@ impl<'p> GenerateAsmValue<'p> for ValueData {
             ValueKind::Branch(v) => v.generate_asm(f, context, value),
             ValueKind::Binary(v) => v.generate_asm(f, context, value),
             ValueKind::Call(v) => v.generate_asm(f, context, value),
+            ValueKind::GlobalAlloc(v) => v.generate_asm(f, context, value),
             /*
             
             ValueKind::Binary(v) => v.generate(f, info, self),
@@ -56,7 +39,22 @@ impl<'p> GenerateAsmValue<'p> for ValueData {
     }
 }
 
+impl<'p> GenerateAsmValue<'p> for GlobalAlloc {
+    type Out = ();
+    fn generate_asm(&self, f : &'p mut File, context : &'p mut ProgramContext, _value : &Value) -> CResult<Self::Out> {
+        match context.program.borrow_value(self.init()).kind() {
+            ValueKind::Integer(a) => {
+                writeln!(f, "  .word {}", a.value())?;
+            },
+            ValueKind::ZeroInit(_z) => {
+                writeln!(f, "  .zero 4")?;
+            },
+            _ => unreachable!()
+        };
 
+        Ok(())
+    }
+}
 
 impl<'p> GenerateAsmValue<'p> for Jump {
     type Out = ();
diff --git a/src/irgen.rs b/src/irgen.rs
index d31074043e0b90eb3bd9ed28e9df6596db5edeec..f5e649d13d8981a52d51874ec1b973b2a4664b89 100644
--- a/src/irgen.rs
+++ b/src/irgen.rs
@@ -2,6 +2,7 @@ mod gen;
 //mod _func;
 mod func;
 mod scopes;
+mod constcalc;
 use crate::ast::CompUnit;
 use gen::GenerateIR;
 use koopa::ir::Program;
@@ -18,6 +19,8 @@ pub enum IRError {
     AdvancedEvaluation(String),
     VoidValue,
     UndefinedLVal(String),
+    EvaluateConstWithCall,
+    EvaluateConstWithVar,
 }
 
 
@@ -27,7 +30,9 @@ impl fmt::Display for IRError {
             Self::VoidValue => write!(f,"use void value in an expression"),
             Self::AdvancedEvaluation(s) => write!(f, "wrong when evaluate binary operator: {}", s),
             Self::UndefinedLVal(s) => write!(f, "{} is undefined", s),
-            Self::NotMemory => write!(f, "store val in a place not memory")
+            Self::NotMemory => write!(f, "store val in a place not memory"),
+            Self::EvaluateConstWithCall => write!(f, "can not use function call in const variable defination"),
+            Self::EvaluateConstWithVar => write!(f, "can not use variable in const variable defination")
         }
     }
 }
diff --git a/src/irgen/constcalc.rs b/src/irgen/constcalc.rs
new file mode 100644
index 0000000000000000000000000000000000000000..1e15ecc42eb20c2bc74eabb36c05a5466f788460
--- /dev/null
+++ b/src/irgen/constcalc.rs
@@ -0,0 +1,153 @@
+use crate::ast::*;
+
+use crate::irgen::scopes::Scopes;
+use crate::irgen::IResult;
+use crate::irgen::IRError;
+
+
+use super::scopes::RecValue;
+
+// just calculate the result to the primitive type : i32
+pub trait PreCalculate<'ast> {
+    fn calculate(&'ast self, scope :&mut Scopes<'ast>) -> IResult<i32>;
+}
+
+impl<'ast> PreCalculate<'ast> for Exp {
+    fn calculate(&'ast self, scope :&mut Scopes<'ast>) -> IResult<i32> {
+        self.lor.calculate(scope)
+    }
+}
+
+impl<'ast> PreCalculate<'ast> for LOrExp {
+    fn calculate(&'ast self, scope :&mut Scopes<'ast>) -> IResult<i32> {
+        match self {
+            Self::LAndAusdruck(a) => a.calculate(scope),
+            Self::LOrAusdruck(lhs, rhs) => {
+                Ok((lhs.calculate(scope)? != 0 || rhs.calculate(scope)? != 0) as i32)
+            }
+        }
+    }
+}
+
+impl<'ast> PreCalculate<'ast> for LAndExp {
+    fn calculate(&'ast self, scope :&mut Scopes<'ast>) -> IResult<i32> {
+        match self {
+            Self::EqAusdruck(a) => a.calculate(scope),
+            Self::LAndAusdruck(lhs, rhs) => {
+                Ok((lhs.calculate(scope)? != 0 && rhs.calculate(scope)? != 0) as i32)
+            }
+        }
+    }
+}
+
+impl<'ast> PreCalculate<'ast> for EqExp {
+    fn calculate(&'ast self, scope :&mut Scopes<'ast>) -> IResult<i32> {
+        match self {
+            Self::RelAusdruck(a) => a.calculate(scope),
+            Self::EqAusdruck(lhs, op, rhs) => {
+                let (a,b) = 
+                (lhs.calculate(scope)?, rhs.calculate(scope)?);
+                
+                match op {
+                    EqOp::Eq => Ok((a == b) as i32),
+                    EqOp::NotEq => Ok((a != b) as i32)
+                }
+            }
+        }
+    }
+}
+
+impl<'ast> PreCalculate<'ast> for RelExp {
+    fn calculate(&'ast self, scope :&mut Scopes<'ast>) -> IResult<i32> {
+        match self {
+            Self::AddAusdruck(a) => a.calculate(scope),
+            Self::RelAusdruck(lhs, op, rhs) => {
+                let (a, b) = (lhs.calculate(scope)?, rhs.calculate(scope)?);
+
+                match op {
+                    RelOp::Ge => Ok((a >= b) as i32),
+                    RelOp::Gt => Ok((a > b) as i32),
+                    RelOp::Le => Ok((a <= b) as i32),
+                    RelOp::Lt => Ok((a < b) as i32)
+                }
+
+            }
+
+        }
+    }
+}
+
+impl<'ast> PreCalculate<'ast> for AddExp {
+    fn calculate(&'ast self, scope :&mut Scopes<'ast>) -> IResult<i32> {
+        match self {
+            Self::MulAusdruck(e) => e.calculate(scope),
+            Self::AddAusdruck(lhs, op, rhs) => {
+                let (a,b) = (lhs.calculate(scope)?, rhs.calculate(scope)?);
+
+                match op {
+                    AddOp::Add => Ok(a + b),
+                    AddOp::Sub => Ok(a - b)
+                }
+            }
+        }
+    }
+}
+
+impl<'ast> PreCalculate<'ast> for MulExp {
+    fn calculate(&'ast self, scope :&mut Scopes<'ast>) -> IResult<i32> {
+        match self {
+            Self::UnaryAusdruck(e) => e.calculate(scope),
+            Self::MulAusdruck(lhs, op, rhs) => {
+                let (a, b) = (lhs.calculate(scope)?, rhs.calculate(scope)?);
+
+                match op {
+                    MulOp::Div => Ok(a / b),
+                    MulOp::Mod => Ok(a % b),
+                    MulOp::Mul => Ok(a * b)
+                }
+            }
+        }
+    }
+}
+
+impl<'ast> PreCalculate<'ast> for UnaryExp {
+    fn calculate(&'ast self, scope :&mut Scopes<'ast>) -> IResult<i32> {
+        match self {
+            Self::PrimaryAusdruck(e) => e.calculate(scope),
+            Self::Call(_) => Err(IRError::EvaluateConstWithCall),
+            Self::UnaryAusdruck(op, num) => {
+                let a = num.calculate(scope)?;
+                match op {
+                    UnaryOp::LNot => Ok(!(a == 0) as i32),
+                    UnaryOp::Negative => Ok(-a),
+                    UnaryOp::Positive => Ok(a)
+                }
+            }
+        }        
+    }
+}
+
+impl<'ast> PreCalculate<'ast> for PrimaryExp {
+    fn calculate(&'ast self, scope :&mut Scopes<'ast>) -> IResult<i32> {
+        match self {
+            Self::Ausdruck(e) => e.calculate(scope),
+            Self::LVal(v) => v.calculate(scope),
+            Self::Number(n) => Ok(*n)
+        }
+    }
+}
+
+impl<'ast> PreCalculate<'ast> for LVal {
+    fn calculate(&'ast self, scope :&mut Scopes<'ast>) -> IResult<i32> {
+        match scope.retrieve_val(self.id.as_str()) {
+            Some(val) => {
+                match val {
+                    RecValue::Const(v) => Ok(v),
+                    RecValue::IrValue(_) => Err(IRError::EvaluateConstWithVar)
+                }
+            },
+            None => Err(IRError::UndefinedLVal(self.id.clone()))
+            
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/irgen/gen.rs b/src/irgen/gen.rs
index d4e8c1febfff469ea6f087743444ec85029967b9..7111e3e029349ba5e6f501964077cbf223732e2d 100644
--- a/src/irgen/gen.rs
+++ b/src/irgen/gen.rs
@@ -4,6 +4,8 @@ mod declgen;
 mod stmtgen;
 mod funcgen;
 
+
+pub use expgen::ExpResult;
 use crate::ast::*;
 
 use koopa::ir::{Type};
@@ -36,13 +38,40 @@ impl<'ast> GenerateIR<'ast> for CompUnit {
         scopes.decl_func("starttime", vec![], Type::get_unit());
 
         scopes.decl_func("stoptime", vec![], Type::get_unit());
-        
-        for func in &self.func_def {
-            func.function_generate_forepart(scopes)?;
-        }
-        for func in &self.func_def {
-            func.generate(scopes)?;
-        }
+        println!("the length of compdefs {}",self.comp_defs.len());
+        self.comp_defs
+        .iter()
+        .try_for_each(|s| match s {
+                CompDef::FuncDef(f) => {
+                    //println!("generate function {}",f.ident);
+                    f.function_generate_forepart(scopes)
+                },
+                _ => Ok(())
+            }
+        )?;
+        // global level
+        scopes.add_level();
+
+        // generate all variable first
+        let _ = self.comp_defs
+        .iter()
+        .try_for_each(|s| match s {
+            CompDef::Decl(d) => {
+                d.generate(scopes)
+            },
+            _ => Ok(())
+        })?;
+
+        self.comp_defs
+        .iter()
+        .try_for_each(|s| match s {
+            CompDef::FuncDef(f) => {
+                f.generate(scopes)
+            },
+            _ => Ok(())
+        })?;
+
+        scopes.minus_level();
         Ok(())
     }
 }
diff --git a/src/irgen/gen/declgen.rs b/src/irgen/gen/declgen.rs
index 141b3900bbce66697aa895d847417a1c05c9fc19..6da74402ae519cb8587d7552d93491c32a11e80c 100644
--- a/src/irgen/gen/declgen.rs
+++ b/src/irgen/gen/declgen.rs
@@ -1,4 +1,5 @@
 use crate::ast::*;
+use crate::irgen::constcalc::PreCalculate;
 
 use koopa::ir::builder_traits::*;
 use koopa::ir::{Type};
@@ -35,17 +36,42 @@ impl<'ast> GenerateIR<'ast> for VarDef {
     type Out = ();
     fn generate(&'ast self, scopes : &mut Scopes<'ast>) 
         -> IResult<Self::Out> {
-        
-        let tar = scopes.create_initial_variable(Type::get_i32(), Some(&self.id));
-        scopes.add_variable_name(&self.id, tar);
-        match &self.init_val {
-            Some(e) => {
-                let res = e.generate(scopes)?.into_int(scopes)?;
-                let store = scopes.new_value().store(res, tar);
-                scopes.function_push_inst(store);
+        let value = match scopes.is_global() {
+            true => {
+                let alloc_val = 
+                match &self.init_val {
+                    Some(v) => {
+                        let res = v.exp.calculate(scopes)?;
+                        scopes.program.new_value().integer(res)
+                        
+                    },
+                    None => scopes.program.new_value().zero_init(Type::get_i32())
+                };
+                let v = scopes
+                .program
+                .new_value()
+                .global_alloc(
+                    alloc_val
+                );
+                scopes.program.set_value_name(v, Some(format!("@{}", self.id)));
+                v
             },
-            None => ()
-        }
+            false => {
+                let tar = scopes.create_initial_variable(Type::get_i32(), Some(&self.id));
+
+                match &self.init_val {
+                    Some(e) => {
+                        let res = e.generate(scopes)?.into_int(scopes)?;
+                        let store = scopes.new_value().store(res, tar);
+                        scopes.function_push_inst(store);
+                    },
+                    None => ()
+                }
+                tar
+            }
+        };
+        
+        scopes.add_variable_name(&self.id, value);
         Ok(())
     }
 }
@@ -73,19 +99,15 @@ impl<'ast> GenerateIR<'ast> for ConstDef {
     fn generate(&'ast self, scopes : &mut Scopes<'ast>) 
         -> IResult<Self::Out> {
         // a temporary method, treat const as variable
-        let tar = scopes.create_initial_variable(Type::get_i32(), Some(&self.id));
-        scopes.add_variable_name(&self.id, tar);
-        let res = self.init_val.generate(scopes)?.into_int(scopes)?;
-        let store = scopes.new_value().store(res, tar);
-
-        scopes.function_push_inst(store);
+        let v = self.init_val.generate(scopes)?;
+        scopes.add_const_value_name(self.id.as_str(), v);
         Ok(())
     }
 }
 
 // generate IR for const val
 impl<'ast> GenerateIR<'ast> for ConstInitVal {
-    type Out = ExpResult;
+    type Out = i32;
     fn generate(&'ast self, scopes : &mut Scopes<'ast>) 
         -> IResult<Self::Out> {
         self.exp.generate(scopes)
diff --git a/src/irgen/gen/expgen.rs b/src/irgen/gen/expgen.rs
index e393da5e4cb79db2d57bf83eea100242f7405934..7d877950e86f1dbe524cc8c35dba947dc18b3ae8 100644
--- a/src/irgen/gen/expgen.rs
+++ b/src/irgen/gen/expgen.rs
@@ -1,9 +1,10 @@
 use crate::ast::*;
+use crate::irgen::constcalc::PreCalculate;
 
 
-use koopa::ir::builder_traits::*;
+use koopa::ir::{builder_traits::*, TypeKind};
 use koopa::ir::{Value, Type, BinaryOp};
-use crate::irgen::scopes::{Scopes};
+use crate::irgen::scopes::{Scopes, RecValue};
 use crate::irgen::{IResult, GenerateIR};
 use crate::irgen::IRError;
 use paste::paste;
@@ -51,7 +52,24 @@ impl<'ast> GenerateIR<'ast> for LVal {
 
             
             let var = scopes.retrieve_val(&self.id).ok_or(IRError::UndefinedLVal(self.id.clone()))?;
-            Ok(ExpResult::IntPtr(var))
+
+            match var {
+                RecValue::Const(v) => Ok(ExpResult::Int(
+                    scopes.new_value().integer(v)
+                )),
+                RecValue::IrValue(v) => {
+                    match scopes.get_value_type(v).kind() {
+                        TypeKind::Pointer(_) => {
+                            Ok(ExpResult::IntPtr(v))
+                        },
+                        TypeKind::Array(_, _) => unimplemented!(),
+                        TypeKind::Int32 => {
+                            Ok(ExpResult::Int(v))
+                        },
+                        _ => unreachable!()
+                    }
+                }
+            }
     }
 }
 
@@ -65,10 +83,10 @@ impl<'ast> GenerateIR<'ast> for Exp {
 
 
 impl<'ast> GenerateIR<'ast> for ConstExp {
-    type Out = ExpResult;
+    type Out = i32;
     fn generate(&'ast self, scopes : &mut Scopes<'ast>) 
         -> IResult<Self::Out> {
-        self.exp.generate(scopes)
+        self.exp.calculate(scopes)
     }
 }
 
@@ -271,93 +289,7 @@ impl<'ast> $trait_name<'ast> for [<$cur Exp>]  {
 
                 scopes.function_push_inst(load_result);
                 Ok(ExpResult::Int(load_result))
-                /*
-                let mut zero: Option<Value> = None;
-                let mut one: Option<Value> = None;
-                let mut final_result: Option<Value> = None;
-                let mut binary_op: Option<BinaryOp> = None;
-                {
-                    let local_handler = LocalHandler::new(program, scopes);
-
-                    // zero and one
-                    zero = Some(local_handler.new_value().integer(0));
-                    one = Some(local_handler.new_value().integer(1));
-
-
-                    // choosee binary operator for land
-                    binary_op = Some(if stringify!($cur) == "LAnd" {
-                        BinaryOp::NotEq
-                    } else {
-                        BinaryOp::Eq
-                    });
-
-                    // generate a initial variable(global in this function) to store the result
-                    // for LAnd, lhs != 0 failed, the result is 0, and we go to end directly
-                    // for LOr,  lhs == 0 failed, the result is 1, and we go to end directly
-
-                    final_result = Some(local_handler.create_initial_variable(Type::get_i32(), None));
-
-                    let store = if stringify!($cur) == "LAnd" {
-                        local_handler.new_value().store(zero.unwrap(), final_result.unwrap())
-                    } else {
-                        local_handler.new_value().store(one.unwrap(), final_result.unwrap())
-                    };
-                    // 1.push the initial result in current block
-                    local_handler.push_inst(program, store);
-                }
-
-                
-                let lhs_result = lhs.generate(program, scopes)?;
-                
-                {
-                    let lhs_comp_result = cur_func!(scopes).new_value(program).binary(binary_op, zero, lhs_result);
-
-                    // 2.add compare result in current block
-                    cur_func!(scopes).push_inst(program, lhs_comp_result);
-
-
-                    // For LAnd and LOr
-                    // if lhs is true, we need to test rhs
-                    // or else we go to end block directly
-
-                    let next_block = cur_func!(scopes).create_new_block(program, Some(concat!("%", stringify!($cur), "_next").to_string()));
-                    let end_block = cur_func!(scopes).create_new_block(program, Some(concat!("%", stringify!($cur),"_end").to_string()));
-
-                    let br = cur_func!(scopes).new_value(program).branch(lhs_comp_result, next_block, end_block);
-                    // 3.add branch to the current block
-                    cur_func!(scopes).push_inst(program, br);
-                    
-                    // 4. add next_block, now next_block is current block
-                    cur_func!(scopes).add_new_block(program, next_block);
-                }
-                // 5. calculate right hand side and add instruction in next_block
-                let rhs_result = rhs.generate(program, scopes)?;
-
-                {
-                    let rhs_comp_result = cur_func!(scopes).new_value(program).binary(binary_op, zero, rhs_result);
-
-                    cur_func!(scopes).push_inst(program, rhs_comp_result);
-
-                    // 6. store the right hand result in final result
-
-                    let store_rhs = cur_func!(scopes).new_value(program).store(rhs_comp_result, final_result);
-
-                    cur_func!(scopes).push_inst(program, store_rhs);
-
-                    // 7. from next_block jump to the end block
-                    let jump_to_end = cur_func!(scopes).new_value(program).jump(end_block);
-
-                    cur_func!(scopes).push_inst(program, jump_to_end);
-
-                    // 8. add end_block as current block
-                    cur_func!(scopes).add_new_block(program, end_block);
-                }
-                /*// 9. load the final result
-                let load_result = cur_func!(scopes).new_value(program).load(final_result);
 
-                cur_func!(scopes).push_inst(program, load_result);*/
-                Ok(ExpResult::IntPtr(final_result.unwrap()))
-            */
             }
             
         }
diff --git a/src/irgen/scopes.rs b/src/irgen/scopes.rs
index ac0bb4cfce9592eedaccca79776fa9449e96bd6c..e61f697dfedf0e9ccb79eabbc315f25ca47126a5 100644
--- a/src/irgen/scopes.rs
+++ b/src/irgen/scopes.rs
@@ -5,12 +5,17 @@ use std::collections::HashMap;
 use std::vec::Vec;
 use super::func::FunctionInfo;
 
+#[derive(Clone)]
+pub enum RecValue {
+    Const(i32),
+    IrValue(Value)
+}
 
 // Value: ValueId
 // Function: FunctionId
 // both need program to find their entities
 pub struct Scopes<'ast> {
-    val_level: Vec<HashMap<&'ast str, Value>>,
+    val_level: Vec<HashMap<&'ast str, RecValue>>,
     function_map: HashMap<&'ast str, Function>,
     pub program: &'ast mut Program,
     pub cur_func: Option<FunctionInfo>,
@@ -92,16 +97,22 @@ impl<'ast> Scopes<'ast> {
 
     // get value type from current function
     pub fn get_value_type(&self, value: Value) -> Type {
-        self
-        .program
-        .func(self.get_func_id())
-        .dfg()
-        .value(value)
-        .ty()
-        .clone()
+        // if the value is the global variable
+        if value.is_global() {
+            self.program.borrow_value(value).ty().clone()
+        } else {
+            self
+            .program
+            .func(self.get_func_id())
+            .dfg()
+            .value(value)
+            .ty()
+            .clone()
+        }
     }
 
-    pub fn retrieve_val(&self, s: &str) -> Option<Value>{
+    // symbol table function
+    pub fn retrieve_val(&self, s: &str) -> Option<RecValue>{
         for h in self.val_level.iter().rev() {
             if let Some(v) = h.get(s) {
                 return Some(v.clone());
@@ -117,6 +128,7 @@ impl<'ast> Scopes<'ast> {
         .new_value()
     }
 
+    
     // close entry of a function
     pub fn close_entry(&mut self, next: BasicBlock) {
         let jump = self.new_value().jump(next);
@@ -193,12 +205,19 @@ impl<'ast> Scopes<'ast> {
         .basic_block(name)
     }
 
-    // add const val into hash set
-    pub fn add_variable_name(&mut self, name: &'ast str, val: Value) {
+    // add const variable into hash set
+    pub fn add_const_value_name(&mut self, name: &'ast str, val: i32) {
+        self.val_level
+        .last_mut()
+        .unwrap()
+        .insert(name, RecValue::Const(val));
+    }
+
+    pub fn add_variable_name(&mut self, name: &'ast str, val : Value) {
         self.val_level
         .last_mut()
         .unwrap()
-        .insert(name, val);
+        .insert(name, RecValue::IrValue(val));
     }
 
     // declare sysl library function
@@ -210,4 +229,10 @@ impl<'ast> Scopes<'ast> {
         .function_map
         .insert(name, func);
     }
+
+    // check if it is the global scope
+
+    pub fn is_global(&self) -> bool {
+        self.val_level.len() == 1
+    }
 }
diff --git a/src/sysy.lalrpop b/src/sysy.lalrpop
index ab40a41575c1814e85e458467b50647aad57bd1b..f6e5194f903376308dc1553bb92285252556bd94 100644
--- a/src/sysy.lalrpop
+++ b/src/sysy.lalrpop
@@ -17,24 +17,28 @@ match {
 
 
 // Full program
-pub CompUnit: CompUnit = <func_def : (FuncDef)* > => CompUnit { <> };
+pub CompUnit: CompUnit = <comp_defs : (CompDef)* > => CompUnit { <> };
 
 
+CompDef: CompDef = {
+  FuncDef => CompDef::FuncDef(<>),
+  Decl => CompDef::Decl(<>)
+}
+
 // Declare variable or const
 Decl : Decl = {
   ConstDecl => Decl::Const(<>),
   VarDecl => Decl::Var(<>)
 }
 
-BType : String = "int" => <>.to_string();
 
-ConstDecl : ConstDecl = "const" BType <def : ConstDef> <mut defs : ("," <ConstDef>)*> ";"=> {
+ConstDecl : ConstDecl = "const" "int" <def : ConstDef> <mut defs : ("," <ConstDef>)*> ";"=> {
   defs.insert(0, def);
   ConstDecl{defs}
 };
 
-// VarDecl       ::= BType VarDef {"," VarDef} ";";
-VarDecl : VarDecl = BType <def : VarDef> <mut defs : ("," <VarDef>)*> ";" => {
+// VarDecl       ::= "int" VarDef {"," VarDef} ";";
+VarDecl : VarDecl = "int" <def : VarDef> <mut defs : ("," <VarDef>)*> ";" => {
   defs.insert(0, def);
   VarDecl{defs}
 };
@@ -58,27 +62,28 @@ InitVal : InitVal = <exp : Exp> => InitVal {<>};
 
 // Function Define , Parameter and Type
 FuncFParam : FuncFParam = {
-  BType <id: Ident> => {
+  "int" <id: Ident> => {
     FuncFParam { <> }
   }
 }
 
 
 FuncDef: FuncDef = {
-  <ty: FuncType> <ident : Ident> "(" ")" <block : Block> => {
-    FuncDef {ty , ident , params : Vec::new(), block}
+  <head : FuncDefHead> ")" <block : Block> => {
+    FuncDef {ty : head.0 , ident: head.1 , params : Vec::new(), block}
   },
-  <ty: FuncType> <ident : Ident> "("
+  <head : FuncDefHead>
     <func_param : FuncFParam> <mut func_params : ("," <FuncFParam>)*>
   ")" <block: Block> => {
     func_params.insert(0, func_param);
-    FuncDef {ty , ident, params : func_params, block}
+    FuncDef {ty: head.0 , ident: head.1 , params : func_params, block}
   }
 }
 
-FuncType: FuncType = {
-  "int" => FuncType::Int,
-  "void" => FuncType::Void
+
+FuncDefHead : (FuncType, String) = {
+  "int" <id: Ident> "(" => (FuncType::Int, id),
+  "void" <id: Ident> "(" => (FuncType::Void, id)
 }
 
 // Block