diff --git a/examples/syntax3.rs b/examples/syntax3.rs
index d8152faf75250b46e6ba14a90a6f691f9a54fa0f..6684e2ae742d2013358c9883eccb1f3fb22f9ff0 100644
--- a/examples/syntax3.rs
+++ b/examples/syntax3.rs
@@ -1,4 +1,29 @@
-fn main() {
+fn main() {}
+
+fn a(mut a: i32) {
     let a = 5;
     let b = { 5 };
 }
+
+fn b(x: bool) -> i32 {
+    if x {
+        1
+    } else {
+        2
+    }
+}
+
+fn c() {
+    b(false);
+    let b = if true {
+        let mut a = 1;
+        while a > 0 {
+            a = a - 1
+        }
+        a
+    } else {
+        {
+            5
+        }
+    };
+}
diff --git a/src/ast/main.rs b/src/ast/main.rs
index fe8cfad51901f18d2ebd33f0e3d70d0e50c5a617..c5c7a4a6934e7366e980eeeba329719a3bedec1f 100644
--- a/src/ast/main.rs
+++ b/src/ast/main.rs
@@ -8,7 +8,6 @@ lalrpop_mod!(pub parser, "/ast/parser.rs");
 use parser::*;
 
 pub mod ast;
-use ast::*;
 
 fn main() {}
 
@@ -21,7 +20,7 @@ pub fn read(file_name: &str) -> std::io::Result<String> {
 
 pub fn parse(file_name: &str) {
     let p = read(file_name).expect("File not found");
-    FunctionParser::new().parse(&p).unwrap()
+    ProgramParser::new().parse(&p).unwrap()
 }
 
 #[test]
diff --git a/src/ast/parser.lalrpop b/src/ast/parser.lalrpop
index 67f5f7887bb5eb195fd5f1fd79175373dcd454ad..4c517cd4615d53be8de67995e9b40fd319eb65f4 100644
--- a/src/ast/parser.lalrpop
+++ b/src/ast/parser.lalrpop
@@ -16,113 +16,118 @@ match {
 
 // A comma separated sequence without trailing comma
 CommaNoTrail<T>: Vec<T> = { 
-    <v:(<T> ",")*> <e:T> => { 
-        let mut v = v;
-        v.push(e);
-        v
-    }
+    <mut v:(<T> ",")*> <e:T> => { v.push(e); v }
+}
+
+Tier<Op,NextTier>: Box<Expr> = {
+    Tier<Op,NextTier> Op NextTier => Box::new(Expr::Op(<>)),
+    NextTier
+};
+
+pub Program: () = {
+    Function*
 }
 
 pub Function: () = {
-    "fn" Id Params ("->" Type)? Block => (),
+    "fn" Id Params ("->" Type)? Block,
 }
 
 pub Params: () = {
-    "()" => (), // seems like a haxx
-    "(" ((Param ",")* Param)? ")" => (),
+    "()", // seems like a haxx
+    "(" (Param ",")* Param? ")",
 }
 
 pub Param:() = {
-    Id ":" Type,
+    "mut"? Id ":" Type,
 }
 
 pub Type:() = {
-    "i32" => (),
-    "bool" => (),
-    "()" => (),
+    "i32",
+    "bool",
+    "()",
 }
 
 pub Block: () = {
-    "{" StmtSeq* "}" => (),
-    "{" StmtSeq* Stmt "}" => (),
+    "{" StmtSeq* "}",
+    "{" StmtSeq* Stmt "}",
 }
 
 pub StmtSeq: () = {
-    Stmt ";" => (),
-    StmtBlock => (),
+    Stmt ";",
+    StmtBlock,
 }
 
 pub StmtBlock: () = {
-    "while" Expr Block => (),
-    "if" Expr Block ("else" Block)? => (),
-    Block => (),
+    "while" Expr Block,
+    "if" Expr Block ("else" Block)?,
+    Block,
 }
 
 pub Stmt: () = {
-    ";" => (),
-    "let" "mut"? Id "=" Expr => (),
-    ExprNoBlock "=" Expr => (),
-    ExprNoBlock => (),
+    ";",
+    "let" "mut"? Id "=" Expr,
+    ExprNoBlock "=" Expr,
+    ExprNoBlock,
 }
 
 
 pub Expr: () = {
-    ExprBlock => (),
-    ExprNoBlock => (),    
+    ExprBlock,
+    ExprNoBlock,    
 }
 
 pub ExprBlock: () = {
-    "if" ExprNoBlock Block "else" Block => (),
-    Block => (),
+    "if" ExprNoBlock Block "else" Block,
+    Block,
 }
 
 // Here is our ordinary expressions
 pub ExprNoBlock: () = {
-    ExprNoBlock "||" Expr0 => (),
-    ExprNoBlock "&&" Expr0 => (),
-    Expr0 => (),
+    ExprNoBlock "||" Expr0,
+    ExprNoBlock "&&" Expr0,
+    Expr0,
 }
 
 
 // Comparison
 pub Expr0: () = {
-    Expr0 "==" Expr1 => (),
-    Expr0 "!=" Expr1 => (),
-    Expr0 ">" Expr1 => (),
-    Expr0 "<" Expr1 => (),
-    Expr1 => (),
+    Expr0 "==" Expr1,
+    Expr0 "!=" Expr1,
+    Expr0 ">" Expr1,
+    Expr0 "<" Expr1,
+    Expr1,
 }
 
 
 // AddSub
 pub Expr1: () = {
-    Expr1 "+" Expr2 => (),
-    Expr1 "-" Expr2 => (),
-    Expr2 => (),
+    Expr1 "+" Expr2,
+    Expr1 "-" Expr2,
+    Expr2,
 }
 
 // MulDiv
 pub Expr2: () = {
-    Expr2 "/" Expr3 => (),
-    Expr2 "*" Expr3 => (),
-    Expr3 => (),
+    Expr2 "/" Expr3,
+    Expr2 "*" Expr3,
+    Expr3,
 }
 
 // Unary
 pub Expr3: () = {
-    "*" Term => (),
-    "&" Term => (),
-    "&" "mut" Term => (),
-    "!" Term => (),
-    Term => (),
+    "*" Term,
+    "&" Term,
+    "&" "mut" Term,
+    "!" Term,
+    Term,
 }
 
 pub Term: () = {
-    Id => (),
-    Num => (),
-    Id "(" CommaNoTrail<Expr> ")" => (),
+    Id,
+    Num,
+    Id "(" CommaNoTrail<Expr> ")",
     
-    "(" Expr ")" => (),
+    "(" Expr ")",
 }