diff --git a/cw/test/Spec.hs b/cw/test/Spec.hs
index bc2a1df1b36df14079fcee8027bc74abff5dd32b..0c6674d4bf7012288c6280a8da235699577a7303 100644
--- a/cw/test/Spec.hs
+++ b/cw/test/Spec.hs
@@ -24,7 +24,8 @@ ex3'1 = LamDef [] (LamApp (LamAbs 1 (LamVar 1)) (LamAbs 1 (LamVar 1)))
 ex3'2 = LamDef [] (LamAbs 1 (LamApp (LamVar 1) (LamAbs 1 (LamVar 1))))
 ex3'3 = LamDef [ ("F",LamAbs 1 (LamVar 1) ) ] (LamAbs 2 (LamApp (LamVar 2) (LamMacro "F")))
 ex3'4 = LamDef [ ("F",LamAbs 1 (LamVar 1) ) ] (LamAbs 2 (LamApp (LamAbs 1 (LamVar 1)) (LamVar 2)))
-ex3'5 = LamDef [ ( "F",LamAbs 1 (LamApp ((LamVar 1) (LamVar 1)) ), ( "G",LamAbs 2 (LamVar 2) ) ] ()
+ex3'5 = LamDef [ ( "F",LamAbs 1 (LamApp (LamVar 1) (LamVar 1)) ), ( "G",LamAbs 2 (LamVar 2) ) ] 
+               (LamApp (LamAbs 1 (LamApp (LamVar 1) (LamVar 1))) (LamAbs 2 (LamVar 2)))
 
 ex3'1Ans = "(\\x1 -> x1) \\x1 -> x1"
 ex3'2Ans = "\\x1 -> x1 \\x1 -> x1"
@@ -33,6 +34,23 @@ ex3'4Ans = "def F = \\x1 -> x1 in \\x2 -> F x2"
 ex3'5Ans = "def F = \\x1 -> x1 x1 in def G = \\x2 -> x2 in F G"
 
 
+ex4'1 = "x1 (x2 x3)"
+ex4'2 = "x1 x2 F"
+ex4'3 = "def F = \\x1-> x1 in \\x2 -> x2 F"
+ex4'4 = "def F = \\x1 -> x1 (def G= \\x1 -> x1 in x1) in \\x2 -> x2"
+ex4'5 = "def F = \\x1 -> x1 in def F = \\x2 -> x2 x1 in x1"
+ex4'6 = "def F = x1 in F"
+ex4'7 = "def F = \\x1 -> x1 x1 in def G = \\x2 -> x2 in F G"
+
+ex4'1Ans = Just (LamDef [] (LamApp (LamVar 1) (LamApp (LamVar 2) (LamVar 3))))
+ex4'2Ans = Just (LamDef [] (LamApp (LamApp (LamVar 1) (LamVar 2)) (LamMacro"F")))
+ex4'3Ans = Just (LamDef  [  ("F",  LamAbs  1  (LamVar  1)  )  ] (LamAbs  2  (LamApp  (LamVar  2)  (LamMacro "F"))))
+ex4'4Ans = Nothing
+ex4'5Ans = Nothing
+ex4'6Ans = Nothing
+ex4'7Ans = Just (LamDef [ ( "F",LamAbs 1 (LamApp (LamVar 1) (LamVar 1)) ), ( "G",LamAbs 2 (LamVar 2) ) ] (LamApp (LamMacro "F") (LamMacro "G")))
+
+
 ------------------------------Printing Functions--------------------------------
 
 
@@ -41,15 +59,25 @@ printGrid [] = return ()
 printGrid (w:ws) = do putStrLn $ intersperse ' ' w
                       printGrid ws
 
-pPrintList :: Show a => [a] -> IO ()
-pPrintList cs = do putStr "["
-                   ppl cs
+splitEvery :: Int -> [a] -> [[a]]
+splitEvery _ [] = []
+splitEvery n list = first : (splitEvery n rest)
+  where
+    (first,rest) = splitAt n list
+
+pPrintList :: Show a => Int -> [a] -> IO ()
+pPrintList val xs = do putStr "["
+                       let (first:rest) = splitEvery val xs
+                       putStr $ (init . tail) $ show first
+                       printRest rest
     where
-      ppl (x:[])     =    putStrLn $ " " ++ show x ++ "]\n"
-      ppl (x:y:[])   =    putStrLn $ " " ++ show x ++ "," ++ show y ++ "]\n"
-      ppl (x:y:z:[]) =    putStrLn $ " " ++ show x ++ "," ++ show y ++ "," ++ show z ++ "]\n"
-      ppl (x:y:z:xs) = do putStrLn $ " " ++ show x ++ "," ++ show y ++ "," ++ show z ++ ","
-                          ppl $ xs
+        printRest :: Show a => [[a]] -> IO ()
+        printRest []     = putStr $ "]\n"
+        printRest (x:xs) = do putStr $ (++) "\n " $ (init . tail) $ show x
+                              printRest xs
+
+zipF :: (a -> b) -> [a] -> [(a,b)]
+zipF f xs = zip xs $ map f xs
 
 
 -------------------------------------Main---------------------------------------
@@ -58,32 +86,36 @@ pPrintList cs = do putStr "["
 main :: IO ()
 main = do challenge1Test
           challenge2Test
+          challenge3Test
+          challenge4Test
 
 
 -----------------------------Challenge 1 Testing--------------------------------
 
 
 assert1 :: WordSearchGrid -> [ (String,Maybe Placement) ] -> [ (String,Maybe Placement) ] -> IO ()
-assert1 grid result correct | result == correct = do putStrLn "Testing Grid:\n"
-                                                     printGrid grid
-                                                     putStrLn "\nExpected Result:"
-                                                     pPrintList correct
-                                                     putStrLn "Passed! Result:"
-                                                     pPrintList result
-                            | otherwise         = do putStrLn "Testing Grid:\n"
-                                                     printGrid grid
-                                                     putStrLn "\nExpected Result:"
-                                                     pPrintList correct
-                                                     putStrLn "Failed! Result:"
-                                                     pPrintList result
+assert1 grid result correct = do putStrLn "Testing Grid:\n"
+                                 printGrid grid
+                                 putStrLn "\nExpected Result:"
+                                 pPrintList 3 correct
+                                 putStrLn ""
+                                 if result == correct then
+                                   do putStrLn "Passed! Result:"
+                                      pPrintList 3 result
+                                 else
+                                   do putStrLn "Failed! Result:"
+                                      pPrintList 3 result
 
 challenge1Test :: IO ()
-challenge1Test = do putStrLn "Challenge 1 Start Test"
+challenge1Test = do putStrLn "========================================="
+                    putStrLn "Challenge 1 Start Test"
                     putStrLn "========================================="
                     assert1 exGrid1'1 (solveWordSearch exWords1'1 exGrid1'1) exAns1'1
+                    putStrLn "\n- - - - - - - - - - - - - - - - - -\n"
                     assert1 exGrid1'2 (solveWordSearch exWords1'2 exGrid1'2) exAns1'2
                     putStrLn "========================================="
-                    putStrLn "Challenge 1 End Test\n"
+                    putStrLn "Challenge 1 End Test"
+                    putStrLn "=========================================\n"
 
 
 -----------------------------Challenge 2 Testing--------------------------------
@@ -93,12 +125,13 @@ assert2 :: WordSearchGrid -> [ (String,Maybe Placement) ] -> IO ()
 assert2 grid answers = do putStrLn "Checking Grid Contains all Given Words:\n"
                           printGrid grid
                           putStrLn "\nWords in Grid:"
-                          pPrintList answers
-                          putStrLn areWordsPresent
-    where
-      areWordsPresent = if foldl1 (||) $ map (\(_,x) -> x == Nothing) answers
-                          then "Not all words present!"
-                          else "All words are present!"
+                          pPrintList 3 answers
+                          if foldl1 (||) $ map ((Nothing/=) . snd) answers then
+                            putStrLn "Passed Test! All words are present!"
+                          else
+                            do putStrLn "Failed Test! Not all words are present"
+                               putStrLn "List of found words:"
+                               pPrintList 3 answers
 
 createAndSolve :: [ String ] -> Double -> IO (WordSearchGrid,[ (String,Maybe Placement) ])
 createAndSolve words maxDensity =   do g <- createWordSearch words maxDensity
@@ -106,19 +139,79 @@ createAndSolve words maxDensity =   do g <- createWordSearch words maxDensity
                                        return (g,soln)
 
 challenge2Test :: IO ()
-challenge2Test = do putStrLn "Challenge 2 Start Test"
+challenge2Test = do putStrLn "========================================="
+                    putStrLn "Challenge 2 Start Test"
                     putStrLn "========================================="
                     (g1,sol1) <- createAndSolve ["WORD","EXAMPLE","SEARCH"] 0.3
                     assert2 g1 sol1
                     putStrLn "========================================="
                     putStrLn "Challenge 2 End Test"
-
+                    putStrLn "=========================================\n"
 
 
 -----------------------------Challenge 3 Testing--------------------------------
 
 
-assert3
+assert3 :: LamMacroExpr -> String -> String -> IO ()
+assert3 macro expected result = do putStrLn "Pretty Printing:"
+                                   putStrLn $ show macro ++ "\n"
+                                   putStrLn "Expected Result:"
+                                   putStrLn $ expected ++ "\n"
+                                   if expected == result then
+                                     putStrLn "Passed! Result:"
+                                   else
+                                     putStrLn "Failed! Result:"
+                                   putStrLn result
+
+challenge3Test :: IO ()
+challenge3Test = do putStrLn "========================================="
+                    putStrLn "Challenge 3 Start Test"
+                    putStrLn "========================================="
+                    assert3 ex3'1 ex3'1Ans (prettyPrint ex3'1)
+                    putStrLn "\n- - - - - - - - - - - - - - - - - -\n"
+                    assert3 ex3'2 ex3'2Ans (prettyPrint ex3'2)
+                    putStrLn "\n- - - - - - - - - - - - - - - - - -\n"
+                    assert3 ex3'3 ex3'3Ans (prettyPrint ex3'3)
+                    putStrLn "\n- - - - - - - - - - - - - - - - - -\n"
+                    assert3 ex3'4 ex3'4Ans (prettyPrint ex3'4)
+                    putStrLn "\n- - - - - - - - - - - - - - - - - -\n"
+                    assert3 ex3'5 ex3'5Ans (prettyPrint ex3'5)
+                    putStrLn "========================================="
+                    putStrLn "Challenge 3 End Test"
+                    putStrLn "=========================================\n"
+
+
+-----------------------------Challenge 4 Testing--------------------------------
 
 
--- challenge3Test
\ No newline at end of file
+assert4 :: String -> Maybe LamMacroExpr -> Maybe LamMacroExpr -> IO ()
+assert4 macro expected result = do putStrLn "Parsing:"
+                                   putStrLn $ macro ++ "\n"
+                                   putStrLn "Expected Result:"
+                                   putStrLn $ show expected ++ "\n"
+                                   if expected == result then
+                                     putStrLn "Passed! Result:"
+                                   else
+                                     putStrLn "Failed! Result:"
+                                   putStrLn $ show result
+
+challenge4Test :: IO ()
+challenge4Test = do putStrLn "========================================="
+                    putStrLn "Challenge 4 Start Test"
+                    putStrLn "========================================="
+                    assert4 ex4'1 ex4'1Ans (parseLamMacro ex4'1)
+                    putStrLn "\n- - - - - - - - - - - - - - - - - -\n"
+                    assert4 ex4'2 ex4'2Ans (parseLamMacro ex4'2)
+                    putStrLn "\n- - - - - - - - - - - - - - - - - -\n"
+                    assert4 ex4'3 ex4'3Ans (parseLamMacro ex4'3)
+                    putStrLn "\n- - - - - - - - - - - - - - - - - -\n"
+                    assert4 ex4'4 ex4'4Ans (parseLamMacro ex4'4)
+                    putStrLn "\n- - - - - - - - - - - - - - - - - -\n"
+                    assert4 ex4'5 ex4'5Ans (parseLamMacro ex4'5)
+                    putStrLn "\n- - - - - - - - - - - - - - - - - -\n"
+                    assert4 ex4'6 ex4'6Ans (parseLamMacro ex4'6)
+                    putStrLn "\n- - - - - - - - - - - - - - - - - -\n"
+                    assert4 ex4'7 ex4'7Ans (parseLamMacro ex4'7)
+                    putStrLn "========================================="
+                    putStrLn "Challenge 4 End Test"
+                    putStrLn "=========================================\n"
\ No newline at end of file