diff --git a/examples/crust.rs b/examples/crust.rs
index f1a7b554c34d250d3a5f016bb74e1cdf7b260118..917e7991a8ccf47f3b6e075776be46ae308b8b78 100644
--- a/examples/crust.rs
+++ b/examples/crust.rs
@@ -1,6 +1,6 @@
 use crust::{
     ast::{Expr, Func, Op, Span, SpanExpr},
-    parse::parse_expr,
+    parse::{parse_block, parse_expr},
 };
 
 use inkwell::{
@@ -16,97 +16,45 @@ use inkwell::{
     FloatPredicate, OptimizationLevel,
 };
 use std::collections::HashMap;
-
 use std::error::Error;
 
 type ExprFunc = unsafe extern "C" fn() -> i32;
 
-fn compile_expr(
-    expr: &SpanExpr,
-    context: &Context,
-    module: &Module,
-    builder: &Builder,
-) -> IntValue {
-    match expr.1.clone() {
-        Expr::Num(i) => context.i32_type().const_int(i as u64, false),
-
-        Expr::BinOp(op, l, r) => {
-            let lv = compile_expr(&l, context, module, builder);
-            let rv = compile_expr(&r, context, module, builder);
-            match op {
-                Op::Add => builder.build_int_add(lv, rv, "sum")
-                ,
-                //         Op::Sub => lv - rv,
-                //         Op::Mul => lv * rv,
-                //         Op::Div => lv / rv,
-                //         Op::Pow => lv.pow(rv as u32),
-                _ => unimplemented!(),
-            }
-        }
-        // Expr::UnaryOp(op, e) => {
-        //     let e = eval_expr(&e);
-        //     match op {
-        //         Op::Add => e,
-        //         Op::Sub => -e,
-        //         _ => unimplemented!(),
-        //     }
-        // }
-        _ => unimplemented!(),
-    }
-}
-
-fn jit_compile_sum(
-    expr: &SpanExpr,
-    context: &Context,
-    module: &Module,
-    builder: &Builder,
-    execution_engine: &ExecutionEngine,
-) -> Option<JitFunction<ExprFunc>> {
-    let u32_type = context.i32_type();
-    let fn_type = u32_type.fn_type(&[], false);
-
-    let function = module.add_function("expr", fn_type, None);
-    let basic_block = context.append_basic_block(&function, "entry");
-
-    builder.position_at_end(&basic_block);
-
-    // let x = context.i32_type().const_int(1, false);
-    // let y = context.i32_type().const_int(42, false);
-    // let z = context.i32_type().const_int(3, false);
-
-    // let sum = builder.build_int_add(x, y, "sum");
-    // let sum = builder.build_int_add(sum, z, "sum");
-    // builder.build_return(Some(&sum));
-    let res = compile_expr(expr, context, module, builder);
-    builder.build_return(Some(&res));
-
-    unsafe { execution_engine.get_function("expr").ok() }
-}
-
 fn main() -> Result<(), Box<dyn Error>> {
     let context = Context::create();
     let mut module = context.create_module("expr");
     let builder = context.create_builder();
+    let fpm = PassManager::create(&module);
+    fpm.initialize();
     let execution_engine =
         module.create_jit_execution_engine(OptimizationLevel::None)?;
 
-    // let passmanager = PassManager::create(input: I)
-
-    match parse_expr(Span::new(
-        "
-        2 + 3
-        ",
-    )) {
-        Ok((_, e)) => {
-            println!("{:?}", &e);
-            let fun_expr = jit_compile_sum(
-                &e,
-                &context,
-                &module,
-                &builder,
-                &execution_engine,
-            )
-            .ok_or("Unable to JIT compile `expr`")?;
+    // match parse_block(Span::new(
+    //     "
+    //     {
+    //         return = 2 + 3;
+    //     }
+    //     ",
+    // ))
+    match parse_expr(Span::new("2 + 3")) {
+        Ok((_, expr)) => {
+            println!("{:?}", &expr);
+            let u32_type = context.i32_type();
+            let fn_type = u32_type.fn_type(&[], false);
+            let function = module.add_function("expr", fn_type, None);
+            let basic_block = context.append_basic_block(&function, "entry");
+            builder.position_at_end(&basic_block);
+
+            let mut compiler = Compiler {
+                context: &context,
+                builder: &builder,
+                module: &module,
+                //&fpm,
+            };
+            let res = compiler.compile_expr(&expr);
+            builder.build_return(Some(&res));
+            let fun_expr: JitFunction<ExprFunc> =
+                unsafe { execution_engine.get_function("expr").ok().unwrap() };
 
             unsafe {
                 println!("{}", fun_expr.call());
@@ -119,30 +67,45 @@ fn main() -> Result<(), Box<dyn Error>> {
     Ok(())
 }
 
-pub fn eval_expr(e: &SpanExpr) -> i32 {
-    match e.1.clone() {
-        Expr::Num(i) => i,
-        Expr::BinOp(op, l, r) => {
-            let lv = eval_expr(&l);
-            let rv = eval_expr(&r);
-            match op {
-                Op::Add => lv + rv,
-                Op::Sub => lv - rv,
-                Op::Mul => lv * rv,
-                Op::Div => lv / rv,
-                Op::Pow => lv.pow(rv as u32),
+pub struct Compiler<'a> {
+    pub context: &'a Context,
+    pub builder: &'a Builder,
+    // pub fpm: &'a PassManager<FunctionValue>,
+    pub module: &'a Module,
+    // pub function: &'a Func<'a>,
+
+    // variables: HashMap<String, PointerValue>,
+    // fn_value_opt: Option<FunctionValue>,
+}
+
+impl<'a> Compiler<'a> {
+    fn compile_expr(&self, expr: &SpanExpr) -> IntValue {
+        match expr.1.clone() {
+            Expr::Num(i) => self.context.i32_type().const_int(i as u64, false),
+
+            Expr::BinOp(op, l, r) => {
+                let lv = self.compile_expr(&l);
+                let rv = self.compile_expr(&r);
+                match op {
+                Op::Add => self.builder.build_int_add(lv, rv, "sum")
+                ,
+                //         Op::Sub => lv - rv,
+                //         Op::Mul => lv * rv,
+                //         Op::Div => lv / rv,
+                //         Op::Pow => lv.pow(rv as u32),
                 _ => unimplemented!(),
             }
-        }
-        Expr::UnaryOp(op, e) => {
-            let e = eval_expr(&e);
-            match op {
-                Op::Add => e,
-                Op::Sub => -e,
-                _ => unimplemented!(),
             }
+            // Expr::UnaryOp(op, e) => {
+            //     let e = eval_expr(&e);
+            //     match op {
+            //         Op::Add => e,
+            //         Op::Sub => -e,
+            //         _ => unimplemented!(),
+            //     }
+            // }
+            _ => unimplemented!(),
         }
-        _ => unimplemented!(),
     }
 }