diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -10,6 +10,6 @@
 ```
 which prints:
 
-    (a) = 2, (a+1) = 3, (map (+1) [1..3]) = [2,3,4]
+    (a) = 2   (a+1) = 3       (map (+1) [1..3]) = [2,3,4]
 
 
diff --git a/dump.cabal b/dump.cabal
--- a/dump.cabal
+++ b/dump.cabal
@@ -2,14 +2,13 @@
 -- see http://haskell.org/cabal/users-guide/
 
 name:               dump
-version:            0.1.2
+version:            0.2.0
 synopsis:           Dumps the names and values of expressions to ease debugging.
 description:        Example: "let a=1 in [d|a, a+1|] == \"(a) = 1, (a+1) = 2\""
 license:            MIT
 license-file:       LICENSE
 author:             Milán Nagy
 maintainer:         dumplibhs.psssst@dfgh.net
-copyright:          ©2015 Milán Nagy
 category:           Development
 build-type:         Simple
 extra-source-files: README.md
@@ -38,8 +37,7 @@
 
 test-suite spec
   type:               exitcode-stdio-1.0
-  build-depends:      dump
-                    , base
+  build-depends:      base
                     , hspec
 
                     , template-haskell
diff --git a/spec/Spec.hs b/spec/Spec.hs
--- a/spec/Spec.hs
+++ b/spec/Spec.hs
@@ -3,14 +3,74 @@
 import Test.Hspec
 
 import Debug.Dump
+import Internal.Parse
+import Text.InterpolatedString.Perl6
 import Utils
 
-main = hspec $ do
+main = spec
+
+spec = hspec $ do
   describe "wrapInParens" $ do
     it "should work" $ do
       wrapInParens "a" `shouldBe` "(a)"
       wrapInParens "" `shouldBe` "()"
 
+  describe "parseExp" $ do
+    it "handles flat" $ do
+      pExp "asd" `shouldBe` "asd"
+      pExp "asd,asd" `shouldBe` "asd"
+      pExp "asd,a,sd" `shouldBe` "asd"
+
+    it "handles parens" $ do
+      pExp "(a,b)" `shouldBe` "(a,b)"
+      pExp "(a,b) (a,b)" `shouldBe` "(a,b) (a,b)"
+      pExp "(a,b), c" `shouldBe` "(a,b)"
+      pExp "((a), b), c" `shouldBe` "((a), b)"
+      pExp "((a,b),(a,b)), a" `shouldBe` "((a,b),(a,b))"
+
+    it "handles char literals" $ do
+      pExp "','" `shouldBe` "','"
+      pExp "',', a" `shouldBe` "','"
+
+    it "handles string literals" $ do
+      pExp [q|","|] `shouldBe` [q|","|]
+      pExp [q|",", a|] `shouldBe` [q|","|]
+
+    it "handles list literals" $ do
+      pExp "[a,b]" `shouldBe` "[a,b]"
+
+    it "treats string literals as leaves" $ do
+      pExp [q|"(", a|] `shouldBe` [q|"("|]
+
+    it "support escaping in leaves" $ do
+      pExp [q|"\"", a|] `shouldBe` [q|"\""|]
+      pExp [q|"a" ++ "b", a|] `shouldBe` [q|"a" ++ "b"|]
+
+    it "misc" $ do
+      pExp [q|"((", a|] `shouldBe` [q|"(("|]
+      pExp [q|"()(", a|] `shouldBe` [q|"()("|]
+      pExp "(a, )" `shouldBe` "(a, )"
+      pExp "(, b)" `shouldBe` "(, b)"
+      -- pExp "([)], a" `shouldBe` "([)]"
+
+  describe "parseExp" $ do
+    it "treats string literals as leaves" $ do
+      pLeaf '"' "a\", b" `shouldBe` "a"
+      pLeaf '"' "a\\\"\", b" `shouldBe` "a\\\""
+      pLeaf '"' "a\\" `shouldBe` "a\\"
+
+  describe "separate" $ do
+    it "should work" $ do
+      separate "a" `shouldBe` ["a"]
+      separate "a,b" `shouldBe` ["a", "b"]
+      separate "a, b" `shouldBe` ["a", " b"]
+      separate "(a)" `shouldBe` ["(a)"]
+      separate "(a, b)" `shouldBe` ["(a, b)"]
+      separate "(a, b), b" `shouldBe` ["(a, b)", " b"]
+      separate "','" `shouldBe` ["','"]
+      separate "a ',' b" `shouldBe` ["a ',' b"]
+      separate "(a, b \")\"), b" `shouldBe` ["(a, b \")\")", " b"]
+
   describe "Debug.Dump" $ do
     -- TODO decide if this is useful enough to warrant support
     -- it "should execute even if empty" $ do
@@ -28,12 +88,11 @@
       [d|a + 1|] `shouldBe` "(a + 1) = 2"
 
     it "should work with comma separated expressions" $ do
-      [d|1, 2|] `shouldBe` "(1) = 1, (2) = 2"
+      [d|1, 2|] `shouldBe` "(1) = 1\t  (2) = 2"
       let i = 0.25
       let f = (1 -)
       [d|i, 1/i, f i, f (1/i)|] `shouldBe`
-        "(i) = 0.25, (1/i) = 4.0, (f i) = 0.75, (f (1/i)) = -3.0"
+        "(i) = 0.25\t  (1/i) = 4.0\t  (f i) = 0.75\t  (f (1/i)) = -3.0"
 
-    -- TODO parser, WIP on 'parse' branch
-    -- it "should step over commas in sub-expressions" $ do
-    --   [d|(1, 2), 1|] `shouldBe` "((1, 1)) = (1,1), (1) = 1"
+    it "should step over commas in sub-expressions" $ do
+      [d|(1, 2), 1|] `shouldBe` "((1, 2)) = (1,2)\t  (1) = 1"
diff --git a/src/Debug/Dump.hs b/src/Debug/Dump.hs
--- a/src/Debug/Dump.hs
+++ b/src/Debug/Dump.hs
@@ -22,7 +22,7 @@
     pairsOf str = join (map pairOf list) $> wrapInParens
       where
         join :: [String] -> String
-        join = intercalate ([q| ++ ", " ++ |] :: String)
+        join = intercalate ([q| ++ "\t  " ++ |] :: String)
         list :: [String]
         list = separate str
     pairOf :: String -> String
@@ -32,3 +32,5 @@
         stripped = strip str
     parse :: String -> Exp
     parse = parseExp .> either error id
+
+
diff --git a/src/Utils.hs b/src/Utils.hs
--- a/src/Utils.hs
+++ b/src/Utils.hs
@@ -2,23 +2,26 @@
 
 import qualified Data.Text as T
 import Text.InterpolatedString.Perl6
+import Debug.Trace
+import Internal.Parse
 
 (.>) = flip (.); infixl 9 .>
 ($>) = flip ($); infixl 0 $>
 
-
 strip  = T.unpack . T.strip . T.pack
 
 wrapInParens :: String -> String
-wrapInParens s = [qq|($s)|]
+wrapInParens = wrapIn "(" ")"
 
+wrapIn :: String -> String -> String -> String
+wrapIn a c b = a ++ b ++ c
+
 separate :: String -> [String]
-separate = wordsWhen (== ',')
+separate = parseSimple
+-- separate = wordsWhen (== ',')
 
--- TODO use parsing to account for [d|1,(2,3)|]
 wordsWhen     :: (Char -> Bool) -> String -> [String]
 wordsWhen p s =  case dropWhile p s of
                       "" -> []
                       s' -> w : wordsWhen p s''
                             where (w, s'') = break p s'
-
