diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,19 @@
+v0.1.4.0
+=======
+
+Features:
+
+* Added `encodeLazy` and `encodeOneLazy` functions to producing lazy
+  text
+
+Fixes:
+
+* Added the `Located` type for source location tracking for `atom`
+  values (thanks ckoparkar!)
+* Added `unconstrainedPrint`, which does not try to restrict a printed
+  s-expression to a fixed width but will attempt to indent it in a
+  reasonable way nonetheless.
+
 v0.1.3.0
 =======
 
diff --git a/Data/SCargot/Print.hs b/Data/SCargot/Print.hs
--- a/Data/SCargot/Print.hs
+++ b/Data/SCargot/Print.hs
@@ -6,6 +6,8 @@
          ( -- * Pretty-Printing
            encodeOne
          , encode
+         , encodeOneLazy
+         , encodeLazy
            -- * Pretty-Printing Control
          , SExprPrinter
          , Indent(..)
@@ -125,16 +127,36 @@
   , indentPrint  = True
   }
 
+data Size = Size
+  { sizeSum :: !Int
+  , sizeMax :: !Int
+  } deriving (Show)
+
 -- | This is an intermediate representation which is like (but not
 -- identical to) a RichSExpr representation. In particular, it has a
 -- special case for empty lists, and it also keeps a single piece of
 -- indent information around for each list
 data Intermediate
   = IAtom Text
-  | IList Indent Intermediate (Seq.Seq Intermediate) (Maybe Text)
+  -- ^ An atom, already serialized
+  | IList Indent Size Intermediate (Seq.Seq Intermediate) (Maybe Text)
+  -- ^ A (possibly-improper) list, with the intended indentation
+  -- strategy, the head of the list, the main set of elements, and the
+  -- final improper element (if it exists)
   | IEmpty
+  -- ^ An empty list
 
+sizeOf :: Intermediate -> Size
+sizeOf IEmpty = Size 2 2
+sizeOf (IAtom t) = Size len len where len = T.length t
+sizeOf (IList _ s _ _ _) = s
 
+concatSize :: Size -> Size -> Size
+concatSize l r = Size
+  { sizeSum = sizeSum l + 1 + sizeSum r
+  , sizeMax = sizeMax l `max` sizeMax r
+  }
+
 toIntermediate :: SExprPrinter a (SExpr a) -> SExpr a -> Intermediate
 toIntermediate
   SExprPrinter { atomPrinter = printAtom
@@ -144,19 +166,22 @@
     headOf (SAtom a)    = IAtom (printAtom a)
     headOf SNil         = IEmpty
     headOf (SCons x xs) =
-      gather (swing x) (headOf x) (Seq.empty) xs
-    gather sw hd rs SNil =
-      IList sw hd rs Nothing
-    gather sw hd rs (SAtom a) =
-      IList sw hd rs (Just (printAtom a))
-    gather sw hd rs (SCons x xs) =
-      gather sw hd (rs Seq.|> headOf x) xs
+      gather (swing x) hd Seq.empty xs (sizeOf hd) where hd = headOf x
+    gather sw hd rs SNil sz =
+      IList sw sz hd rs Nothing
+    gather sw hd rs (SAtom a) sz =
+      IList sw (sz `concatSize` aSize) hd rs (Just aStr)
+        where aSize = Size (T.length aStr) (T.length aStr)
+              aStr = printAtom a
+    gather sw hd rs (SCons x xs) sz =
+      gather sw hd (rs Seq.|> x') xs (sz `concatSize` sizeOf x')
+        where x' = headOf x
 
 
 unboundIndentPrintSExpr :: SExprPrinter a (SExpr a) -> SExpr a -> TL.Text
 unboundIndentPrintSExpr spec = finalize . go . toIntermediate spec
   where
-    finalize = B.toLazyText . F.foldMap (<> B.fromString "\n")
+    finalize = B.toLazyText . joinLinesS
 
     go :: Intermediate -> Seq.Seq B.Builder
     go (IAtom t) = Seq.singleton (B.fromText t)
@@ -164,7 +189,7 @@
     -- this case should never be called with an empty argument to
     -- @values@, as that should have been translated to @IEmpty@
     -- instead.
-    go (IList iv initial values rest)
+    go (IList iv _ initial values rest)
       -- if we're looking at an s-expression that has no nested
       -- s-expressions, then we might as well consider it flat and let
       -- it take the whole line
@@ -207,8 +232,6 @@
             let hd = B.fromString "(" <> buildUnwords (F.foldMap go (Seq.fromList [initial, y]))
                 butLast = hd Seq.<| fmap (doIndentOf (fromIntegral len)) (F.foldMap go ys)
             in handleTail rest butLast
-            -- B.fromString "(" <> buildUnwords (F.foldMap go (Seq.fromList [x, y]))
-            -- Seq.<| fmap (doIndentOf (fromIntegral len)) (handleTail rest (F.foldMap go ys))
 
     doIndent :: B.Builder -> B.Builder
     doIndent = doIndentOf (indentAmount spec)
@@ -224,7 +247,7 @@
     handleTail :: Maybe Text -> Seq.Seq B.Builder -> Seq.Seq B.Builder
     handleTail Nothing = insertCloseParen
     handleTail (Just t) =
-      (Seq.|> (B.fromString "." <> B.fromText t <> B.fromString ")"))
+      (Seq.|> (B.fromString " . " <> B.fromText t <> B.fromString ")"))
 
     insertCloseParen :: Seq.Seq B.Builder -> Seq.Seq B.Builder
     insertCloseParen s = case Seq.viewr s of
@@ -237,7 +260,7 @@
       t Seq.:< ts -> t <> F.foldMap (\ x -> B.fromString " " <> x) ts
 
     pTail Nothing = B.fromString ")"
-    pTail (Just t) = B.fromString ". " <> B.fromText t <> B.fromString ")"
+    pTail (Just t) = B.fromString " . " <> B.fromText t <> B.fromString ")"
 
     ppBasic (IAtom t) = Just (B.fromText t)
     ppBasic (IEmpty) = Just (B.fromString "()")
@@ -302,21 +325,21 @@
 
 
 -- Indents a line by n spaces
-indent :: Int -> Text -> Text
-indent n ts = T.replicate n " " <> ts
+indent :: Int -> B.Builder -> B.Builder
+indent n ts = B.fromText (T.replicate n " ") <> ts
 
 
 -- Sort of like 'unlines' but without the trailing newline
-joinLinesS :: Seq.Seq Text -> Text
+joinLinesS :: Seq.Seq B.Builder -> B.Builder
 joinLinesS s = case Seq.viewl s of
   Seq.EmptyL -> ""
   t Seq.:< ts
     | F.null ts -> t
-    | otherwise -> t <> "\n" <> joinLinesS ts
+    | otherwise -> t <> B.fromString "\n" <> joinLinesS ts
 
 
 -- Sort of like 'unlines' but without the trailing newline
-unwordsS :: Seq.Seq Text -> Text
+unwordsS :: Seq.Seq B.Builder -> B.Builder
 unwordsS s = case Seq.viewl s of
   Seq.EmptyL -> ""
   t Seq.:< ts
@@ -326,19 +349,18 @@
 
 -- Indents every line n spaces, and adds a newline to the beginning
 -- used in swung indents
-indentAllS :: Int -> Seq.Seq Text -> Text
+indentAllS :: Int -> Seq.Seq B.Builder -> B.Builder
 indentAllS n = ("\n" <>) . joinLinesS . fmap (indent n)
 
 
 -- Indents every line but the first by some amount
 -- used in aligned indents
-indentSubsequentS :: Int -> Seq.Seq Text -> Text
+indentSubsequentS :: Int -> Seq.Seq B.Builder -> B.Builder
 indentSubsequentS n s = case Seq.viewl s of
   Seq.EmptyL -> ""
   t Seq.:< ts
     | F.null ts -> t
     | otherwise -> joinLinesS (t Seq.<| fmap (indent n) ts)
---      where go = fmap (indent n)
 
 
 -- oh god this code is so disgusting
@@ -348,27 +370,32 @@
 
 -- | Pretty-print a 'SExpr' according to the options in a
 --   'LayoutOptions' value.
-prettyPrintSExpr :: SExprPrinter a (SExpr a) -> SExpr a -> Text
+prettyPrintSExpr :: SExprPrinter a (SExpr a) -> SExpr a -> TL.Text
 prettyPrintSExpr pr@SExprPrinter { .. } expr = case maxWidth of
   Nothing
-    | indentPrint -> TL.toStrict (unboundIndentPrintSExpr pr (fromCarrier expr))
+    | indentPrint -> unboundIndentPrintSExpr pr (fromCarrier expr)
     | otherwise   -> flatPrintSExpr (fmap atomPrinter (fromCarrier expr))
-  Just _  -> indentPrintSExpr' pr expr
+  Just w  -> indentPrintSExpr' w pr expr
 
 
-indentPrintSExpr' :: SExprPrinter a (SExpr a) -> SExpr a -> Text
-indentPrintSExpr' pr@SExprPrinter { .. } = pp 0 . toIntermediate pr
+indentPrintSExpr' :: Int -> SExprPrinter a (SExpr a) -> SExpr a -> TL.Text
+indentPrintSExpr' maxAmt pr@SExprPrinter { .. } = B.toLazyText . pp 0 . toIntermediate pr
   where
-    pp _   IEmpty         = "()"
-    pp _   (IAtom t)    = t
-    pp ind (IList i h values end) = "(" <> hd <> body <> tl <> ")"
+    pp _   IEmpty       = B.fromString "()"
+    pp _   (IAtom t)    = B.fromText t
+    pp ind (IList i sz h values end) =
+      -- we always are going to have a head, a (possibly empty) body,
+      -- and a (possibly empty) tail in our list formats
+      B.fromString "(" <> hd <> body <> tl <> B.fromString ")"
       where
+        -- the tail is either nothing, or the final dotted pair
         tl = case end of
-               Nothing -> ""
-               Just x  -> " . " <> x
+               Nothing -> mempty
+               Just x  -> B.fromString " . " <> B.fromText x
+        -- the head is the pretty-printed head, with an ambient
+        -- indentation of +1 to account for the left paren
         hd = pp (ind+1) h
-        flat = unwordsS (fmap (pp (ind + 1)) values)
-        headWidth = T.length hd + 1
+        headWidth = sizeSum (sizeOf h)
         indented =
           case i of
             SwingAfter n ->
@@ -384,16 +411,21 @@
               indentSubsequentS (ind + headWidth + 1)
                 (fmap (pp (ind + headWidth + 1)) values)
         body
-          | length values == 0 = ""
-          | Just maxAmt <- maxWidth
-          , T.length flat + ind > maxAmt = " " <> indented
-          | otherwise = " " <> flat
+          -- if there's nothing here, then we don't have anything to
+          -- indent
+          | length values == 0 = mempty
+          -- if we can't fit the whole next s-expression on the same
+          -- line, then we use the indented form
+          | sizeSum sz + ind > maxAmt = B.fromString " " <> indented
+          | otherwise =
+            -- otherwise we print the whole thing on one line!
+            B.fromString " " <> unwordsS (fmap (pp (ind + 1)) values)
 
 
 -- if we don't indent anything, then we can ignore a bunch of the
 -- details above
-flatPrintSExpr :: SExpr Text -> Text
-flatPrintSExpr = TL.toStrict . B.toLazyText . pHead
+flatPrintSExpr :: SExpr Text -> TL.Text
+flatPrintSExpr = B.toLazyText . pHead
   where
     pHead (SCons x xs) =
       B.fromString "(" <> pHead x <> pTail xs
@@ -413,9 +445,21 @@
 --   'SExprPrinter'.
 encodeOne :: SExprPrinter atom carrier -> carrier -> Text
 encodeOne s@(SExprPrinter { .. }) =
-  prettyPrintSExpr (s { fromCarrier = id }) . fromCarrier
+  TL.toStrict . prettyPrintSExpr (s { fromCarrier = id }) . fromCarrier
 
 -- | Turn a list of s-expressions into a single string according to
 --   a given 'SExprPrinter'.
 encode :: SExprPrinter atom carrier -> [carrier] -> Text
-encode spec = T.intercalate "\n\n" . map (encodeOne spec)
+encode spec =
+  T.intercalate "\n\n" . map (encodeOne spec)
+
+-- | Turn a single s-expression into a lazy 'Text' according to a given
+--   'SExprPrinter'.
+encodeOneLazy :: SExprPrinter atom carrier -> carrier -> TL.Text
+encodeOneLazy s@(SExprPrinter { .. }) =
+  prettyPrintSExpr (s { fromCarrier = id }) . fromCarrier
+
+-- | Turn a list of s-expressions into a lazy 'Text' according to
+--   a given 'SExprPrinter'.
+encodeLazy :: SExprPrinter atom carrier -> [carrier] -> TL.Text
+encodeLazy spec = TL.intercalate "\n\n" . map (encodeOneLazy spec)
diff --git a/s-cargot.cabal b/s-cargot.cabal
--- a/s-cargot.cabal
+++ b/s-cargot.cabal
@@ -1,5 +1,5 @@
 name:                s-cargot
-version:             0.1.3.0
+version:             0.1.4.0
 synopsis:            A flexible, extensible s-expression library.
 homepage:            https://github.com/aisamanra/s-cargot
 description:         S-Cargot is a library for working with s-expressions in
@@ -19,7 +19,9 @@
 build-type:          Simple
 cabal-version:       >=1.10
 bug-reports:         https://github.com/aisamanra/s-cargot/issues
-extra-source-files:  README.md, CHANGELOG.md
+extra-source-files:  README.md,
+                     CHANGELOG.md,
+                     test/*.sexp
 
 source-repository head
   type: git
@@ -29,6 +31,7 @@
   description: Build example application
   default:     False
 
+
 library
   exposed-modules:     Data.SCargot,
                        Data.SCargot.Repr,
@@ -50,6 +53,7 @@
   default-extensions:  CPP
   ghc-options:         -Wall
 
+
 executable example
   if !flag(build-example)
     buildable:         False
@@ -63,6 +67,7 @@
   default-language:    Haskell2010
   ghc-options:         -threaded -rtsopts -with-rtsopts=-N
 
+
 test-suite s-cargot-qc
   default-language: Haskell2010
   type:             exitcode-stdio-1.0
@@ -72,4 +77,16 @@
                     base          >=4.7 && <5,
                     parsec        >=3.1 && <4,
                     QuickCheck    >=2.8 && <3,
+                    text          >=1.2 && <2
+
+
+test-suite s-cargot-printparse
+  default-language: Haskell2010
+  type:             exitcode-stdio-1.0
+  hs-source-dirs:   test
+  main-is:          SCargotPrintParse.hs
+  build-depends:    s-cargot,
+                    base          >=4.7 && <5,
+                    parsec        >=3.1 && <4,
+                    HUnit         >=1.6 && <1.7,
                     text          >=1.2 && <2
diff --git a/test/SCargotPrintParse.hs b/test/SCargotPrintParse.hs
new file mode 100644
--- /dev/null
+++ b/test/SCargotPrintParse.hs
@@ -0,0 +1,279 @@
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE LambdaCase #-}
+
+module Main where
+
+import           Data.Either
+import           Data.SCargot
+import           Data.SCargot.Comments
+import           Data.SCargot.Repr
+import           Data.Semigroup
+import qualified Data.Text as T
+import qualified Data.Text.IO as TIO
+import           System.Exit
+import           Test.HUnit
+import           Text.Parsec as P
+import           Text.Parsec.Text (Parser)
+import           Text.Printf ( printf )
+
+
+main = do
+  putStrLn "Parsing a large S-expression"
+  srcs <- mapM (\n -> (,) n <$> TIO.readFile n) [ "test/small-sample.sexp"
+                                                , "test/med-sample.sexp"
+                                                , "test/med2-sample.sexp"
+                                                , "test/big-sample.sexp"
+                                                ]
+  counts <- runTestTT $ TestList
+            [ TestLabel "basic checks" $ TestList
+              [ TestLabel "flat print" $ TestList
+                [ TestLabel "flatprint SNil" $ "()" ~=? printSExpr SNil
+                , TestLabel "flatprint SAtom" $ "hi" ~=? printSExpr (SAtom (AIdent "hi"))
+                , TestLabel "flatprint pair" $ "(hi . world)" ~=?
+                  printSExpr (SCons (SAtom (AIdent "hi")) (SAtom (AIdent "world")))
+                , TestLabel "flatprint list of 1" $ "(hi)" ~=?
+                  printSExpr (SCons (SAtom (AIdent "hi")) SNil)
+                , TestLabel "flatprint list of 2" $ "(hi world)" ~=?
+                  printSExpr (SCons (SAtom (AIdent "hi"))
+                                    (SCons (SAtom (AIdent "world"))
+                                           SNil))
+                , TestLabel "flatprint list of 2 pairs" $ "((hi . hallo) world . welt)" ~=?
+                  printSExpr (SCons (SCons (SAtom (AIdent "hi"))
+                                           (SAtom (AIdent "hallo")))
+                                    (SCons (SAtom (AIdent "world"))
+                                           (SAtom (AIdent "welt"))))
+                , TestLabel "flatprint list of 3 ending in a pair" $ "(hi world hallo . welt)" ~=?
+                  printSExpr (SCons (SAtom (AIdent "hi"))
+                                    (SCons (SAtom (AIdent "world"))
+                                           (SCons (SAtom (AIdent "hallo"))
+                                                  (SAtom (AIdent "welt")))))
+                , TestLabel "flatprint list of 3" $ "(hi world hallo)" ~=?
+                  printSExpr (SCons (SAtom (AIdent "hi"))
+                                    (SCons (SAtom (AIdent "world"))
+                                           (SCons (SAtom (AIdent "hallo"))
+                                                  SNil)))
+                ]
+
+              , TestLabel "pretty print" $
+                let pprintIt = pprintSExpr 40 Swing in TestList
+                [ TestLabel "pretty print SNil" $ "()" ~=? pprintIt SNil
+                , TestLabel "pretty print SAtom" $ "hi" ~=? pprintIt (SAtom (AIdent "hi"))
+                , TestLabel "pretty print pair" $ "(hi . world)" ~=?
+                  pprintIt (SCons (SAtom (AIdent "hi")) (SAtom (AIdent "world")))
+                , TestLabel "pretty print list of 1" $ "(hi)" ~=?
+                  pprintIt (SCons (SAtom (AIdent "hi")) SNil)
+                , TestLabel "pretty print list of 2" $ "(hi world)" ~=?
+                  pprintIt (SCons (SAtom (AIdent "hi"))
+                                  (SCons (SAtom (AIdent "world"))
+                                         SNil))
+                , TestLabel "pretty print list of 2 pairs" $
+                  "((hi . hallo) world . welt)" ~=?
+                  pprintIt (SCons (SCons (SAtom (AIdent "hi"))
+                                         (SAtom (AIdent "hallo")))
+                                  (SCons (SAtom (AIdent "world"))
+                                         (SAtom (AIdent "welt"))))
+                , TestLabel "pretty print list of 3 ending in a pair" $
+                  "(hi world hallo . welt)" ~=?
+                  pprintIt (SCons (SAtom (AIdent "hi"))
+                                  (SCons (SAtom (AIdent "world"))
+                                         (SCons (SAtom (AIdent "hallo"))
+                                                (SAtom (AIdent "welt")))))
+                , TestLabel "pretty print list of 3" $ "(hi world hallo)" ~=?
+                  pprintIt (SCons (SAtom (AIdent "hi"))
+                                  (SCons (SAtom (AIdent "world"))
+                                         (SCons (SAtom (AIdent "hallo"))
+                                                SNil)))
+                ]
+
+              , TestLabel "unconstrained print" $
+                let pprintIt = ucPrintSExpr Swing in TestList
+                [ TestLabel "pretty print SNil" $ "()" ~=? pprintIt SNil
+                , TestLabel "pretty print SAtom" $ "hi" ~=? pprintIt (SAtom (AIdent "hi"))
+                , TestLabel "pretty print pair" $ "(hi . world)" ~=?
+                  pprintIt (SCons (SAtom (AIdent "hi")) (SAtom (AIdent "world")))
+                , TestLabel "pretty print list of 1" $ "(hi)" ~=?
+                  pprintIt (SCons (SAtom (AIdent "hi")) SNil)
+                , TestLabel "pretty print list of 2" $ "(hi world)" ~=?
+                  pprintIt (SCons (SAtom (AIdent "hi"))
+                                  (SCons (SAtom (AIdent "world"))
+                                         SNil))
+                , TestLabel "pretty print list of 2 pairs" $
+                  "((hi . hallo)\n world\n . welt)" ~=?
+                  pprintIt (SCons (SCons (SAtom (AIdent "hi"))
+                                         (SAtom (AIdent "hallo")))
+                                  (SCons (SAtom (AIdent "world"))
+                                         (SAtom (AIdent "welt"))))
+                , TestLabel "pretty print list of 3 ending in a pair" $
+                  "(hi world hallo . welt)" ~=?
+                  pprintIt (SCons (SAtom (AIdent "hi"))
+                                  (SCons (SAtom (AIdent "world"))
+                                         (SCons (SAtom (AIdent "hallo"))
+                                                (SAtom (AIdent "welt")))))
+                , TestLabel "pretty print list of 3" $ "(hi world hallo)" ~=?
+                  pprintIt (SCons (SAtom (AIdent "hi"))
+                                  (SCons (SAtom (AIdent "world"))
+                                         (SCons (SAtom (AIdent "hallo"))
+                                                SNil)))
+                ]
+
+              ]
+            , TestLabel "round-trip" $ TestList $
+              concatMap (\t -> map t srcs) $
+              [ testParsePrint
+              ]
+            ]
+  if errors counts + failures counts > 0
+  then exitFailure
+  else exitSuccess
+
+
+testParsePrint :: (String, T.Text) -> Test
+testParsePrint (n,s) = TestList
+                       [ testParseFlatPrint n s
+
+                       , testParseUnconstrainedPrint Swing n s
+                       , testParseUnconstrainedPrint Align n s
+
+                       , testParsePPrint 80 Swing n s
+                       , testParsePPrint 60 Swing n s
+                       , testParsePPrint 40 Swing n s
+                       , testParsePPrint 20 Swing n s
+                       , testParsePPrint 15 Swing n s
+                       , testParsePPrint 10 Swing n s
+
+                       , testParsePPrint 80 Align n s
+                       , testParsePPrint 40 Align n s
+                       , testParsePPrint 10 Align n s
+                       ]
+
+
+testParseFlatPrint testName src =
+    testRoundTrip (testName <> " flat print")
+                      (fromRight (error "Failed parse") . parseSExpr)
+                      printSExpr
+                      stripAllText
+                      src
+
+testParseUnconstrainedPrint indentStyle testName src =
+    testRoundTrip (testName <> " unconstrained print")
+                      (fromRight (error "Failed parse") . parseSExpr)
+                      (ucPrintSExpr indentStyle)
+                      stripAllText
+                      src
+
+testParsePPrint width indentStyle testName src =
+    testRoundTrip (testName <> " pretty print")
+                      (fromRight (error "Failed parse") . parseSExpr)
+                      (pprintSExpr width indentStyle)
+                      stripAllText
+                      src
+
+stripAllText = T.unwords . concatMap T.words . T.lines
+
+testRoundTrip nm there back prep src = TestList
+  [ TestLabel (nm <> " round trip") $
+    TestCase $ (prep src) @=? (prep $ back $ there src)
+
+  , TestLabel (nm <> " round trip twice") $
+    TestCase $ (prep src) @=? (prep $ back $ there $ back $ there src)
+  ]
+
+
+------------------------------------------------------------------------
+
+data FAtom = AIdent String
+           | AQuoted String
+           | AString String
+           | AInt Integer
+           | ABV Int Integer
+           deriving (Eq, Show)
+
+
+string :: String -> SExpr FAtom
+string = SAtom . AString
+
+-- | Lift an unquoted identifier.
+ident :: String -> SExpr FAtom
+ident = SAtom . AIdent
+
+-- | Lift a quoted identifier.
+quoted :: String -> SExpr FAtom
+quoted = SAtom . AQuoted
+
+-- | Lift an integer.
+int :: Integer -> SExpr FAtom
+int = SAtom . AInt
+
+
+printAtom :: FAtom -> T.Text
+printAtom a =
+  case a of
+    AIdent s -> T.pack s
+    AQuoted s -> T.pack ('\'' : s)
+    AString s -> T.pack (show s)
+    AInt i -> T.pack (show i)
+    ABV w val -> formatBV w val
+
+
+printSExpr :: SExpr FAtom -> T.Text
+printSExpr = encodeOne (flatPrint printAtom)
+
+pprintSExpr :: Int -> Indent -> SExpr FAtom -> T.Text
+pprintSExpr w i = encodeOne (setIndentStrategy (const i) $
+                             setMaxWidth w $
+                             setIndentAmount 1 $
+                             basicPrint printAtom)
+
+ucPrintSExpr :: Indent -> SExpr FAtom -> T.Text
+ucPrintSExpr i = encodeOne (setIndentStrategy (const i) $
+                            setIndentAmount 1 $
+                            unconstrainedPrint printAtom)
+
+getIdent :: FAtom -> Maybe String
+getIdent (AIdent s) = Just s
+getIdent _ = Nothing
+
+formatBV :: Int -> Integer -> T.Text
+formatBV w val = T.pack (prefix ++ printf fmt val)
+  where
+    (prefix, fmt)
+      | w `rem` 4 == 0 = ("#x", "%0" ++ show (w `div` 4) ++ "x")
+      | otherwise = ("#b", "%0" ++ show w ++ "b")
+
+parseIdent :: Parser String
+parseIdent = (:) <$> first <*> P.many rest
+  where first = P.letter P.<|> P.oneOf "+-=<>_"
+        rest = P.letter P.<|> P.digit P.<|> P.oneOf "+-=<>_"
+
+parseString :: Parser String
+parseString = do
+  _ <- P.char '"'
+  s <- P.many (P.noneOf ['"'])
+  _ <- P.char '"'
+  return s
+
+parseBV :: Parser (Int, Integer)
+parseBV = P.char '#' >> ((P.char 'b' >> parseBin) P.<|> (P.char 'x' >> parseHex))
+  where parseBin = P.oneOf "10" >>= \d -> parseBin' (1, if d == '1' then 1 else 0)
+
+        parseBin' :: (Int, Integer) -> Parser (Int, Integer)
+        parseBin' (bits, x) = do
+          P.optionMaybe (P.oneOf "10") >>= \case
+            Just d -> parseBin' (bits + 1, x * 2 + (if d == '1' then 1 else 0))
+            Nothing -> return (bits, x)
+
+        parseHex = (\s -> (length s * 4, read ("0x" ++ s))) <$> P.many1 P.hexDigit
+
+parseAtom :: Parser FAtom
+parseAtom
+  =   AIdent      <$> parseIdent
+  P.<|> AQuoted     <$> (P.char '\'' >> parseIdent)
+  P.<|> AString     <$> parseString
+  P.<|> AInt . read <$> P.many1 P.digit
+  P.<|> uncurry ABV <$> parseBV
+
+parserLL :: SExprParser FAtom (SExpr FAtom)
+parserLL = withLispComments (mkParser parseAtom)
+
+parseSExpr :: T.Text -> Either String (SExpr FAtom)
+parseSExpr = decodeOne parserLL
diff --git a/test/big-sample.sexp b/test/big-sample.sexp
new file mode 100644
--- /dev/null
+++ b/test/big-sample.sexp
@@ -0,0 +1,1 @@
+((operands ((rD . 'GPR) (setcc . 'Cc_out) (predBits . 'Pred) (mimm . 'Mod_imm) (rN . 'GPR))) (in (mimm setcc rN 'CPSR 'PC)) (defs (('PC (ite ((_ call "arm.is_r15") rD) (ite (bveq #b0 ((_ extract 0 0) ((_ extract 31 0) (bvadd (bvadd ((_ zero_extend 1) rN) ((_ zero_extend 1) (ite (bveq (bvshl #x00000001 ((_ zero_extend 28) ((_ call "a32.modimm_rot") mimm))) #x00000000) ((_ zero_extend 24) ((_ call "a32.modimm_imm") mimm)) (bvor (bvshl (bvshl #x00000001 ((_ zero_extend 28) ((_ call "a32.modimm_rot") mimm))) (bvsub #x00000020 (bvurem ((_ zero_extend 24) ((_ call "a32.modimm_imm") mimm)) #x00000020))) (bvlshr (bvshl #x00000001 ((_ zero_extend 28) ((_ call "a32.modimm_rot") mimm))) (bvurem ((_ zero_extend 24) ((_ call "a32.modimm_imm") mimm)) #x00000020)))))) ((_ zero_extend 1) #x00000000))))) (bvand #xfffffffe ((_ extract 31 0) (bvadd (bvadd ((_ zero_extend 1) rN) ((_ zero_extend 1) (ite (bveq (bvshl #x00000001 ((_ zero_extend 28) ((_ call "a32.modimm_rot") mimm))) #x00000000) ((_ zero_extend 24) ((_ call "a32.modimm_imm") mimm)) (bvor (bvshl (bvshl #x00000001 ((_ zero_extend 28) ((_ call "a32.modimm_rot") mimm))) (bvsub #x00000020 (bvurem ((_ zero_extend 24) ((_ call "a32.modimm_imm") mimm)) #x00000020))) (bvlshr (bvshl #x00000001 ((_ zero_extend 28) ((_ call "a32.modimm_rot") mimm))) (bvurem ((_ zero_extend 24) ((_ call "a32.modimm_imm") mimm)) #x00000020)))))) ((_ zero_extend 1) #x00000000)))) (ite (bveq #b0 ((_ extract 1 1) ((_ extract 31 0) (bvadd (bvadd ((_ zero_extend 1) rN) ((_ zero_extend 1) (ite (bveq (bvshl #x00000001 ((_ zero_extend 28) ((_ call "a32.modimm_rot") mimm))) #x00000000) ((_ zero_extend 24) ((_ call "a32.modimm_imm") mimm)) (bvor (bvshl (bvshl #x00000001 ((_ zero_extend 28) ((_ call "a32.modimm_rot") mimm))) (bvsub #x00000020 (bvurem ((_ zero_extend 24) ((_ call "a32.modimm_imm") mimm)) #x00000020))) (bvlshr (bvshl #x00000001 ((_ zero_extend 28) ((_ call "a32.modimm_rot") mimm))) (bvurem ((_ zero_extend 24) ((_ call "a32.modimm_imm") mimm)) #x00000020)))))) ((_ zero_extend 1) #x00000000))))) (bvand #xfffffffd ((_ extract 31 0) (bvadd (bvadd ((_ zero_extend 1) rN) ((_ zero_extend 1) (ite (bveq (bvshl #x00000001 ((_ zero_extend 28) ((_ call "a32.modimm_rot") mimm))) #x00000000) ((_ zero_extend 24) ((_ call "a32.modimm_imm") mimm)) (bvor (bvshl (bvshl #x00000001 ((_ zero_extend 28) ((_ call "a32.modimm_rot") mimm))) (bvsub #x00000020 (bvurem ((_ zero_extend 24) ((_ call "a32.modimm_imm") mimm)) #x00000020))) (bvlshr (bvshl #x00000001 ((_ zero_extend 28) ((_ call "a32.modimm_rot") mimm))) (bvurem ((_ zero_extend 24) ((_ call "a32.modimm_imm") mimm)) #x00000020)))))) ((_ zero_extend 1) #x00000000)))) ((_ extract 31 0) (bvadd (bvadd ((_ zero_extend 1) rN) ((_ zero_extend 1) (ite (bveq (bvshl #x00000001 ((_ zero_extend 28) ((_ call "a32.modimm_rot") mimm))) #x00000000) ((_ zero_extend 24) ((_ call "a32.modimm_imm") mimm)) (bvor (bvshl (bvshl #x00000001 ((_ zero_extend 28) ((_ call "a32.modimm_rot") mimm))) (bvsub #x00000020 (bvurem ((_ zero_extend 24) ((_ call "a32.modimm_imm") mimm)) #x00000020))) (bvlshr (bvshl #x00000001 ((_ zero_extend 28) ((_ call "a32.modimm_rot") mimm))) (bvurem ((_ zero_extend 24) ((_ call "a32.modimm_imm") mimm)) #x00000020)))))) ((_ zero_extend 1) #x00000000))))) (bvadd 'PC #x00000004))) ('CPSR (ite (ite (andp (bveq #b1 ((_ extract 0 0) predBits)) (bvne predBits #xf)) (notp (ite (bveq ((_ extract 3 1) predBits) #b000) (bveq #b1 ((_ extract 30 30) 'CPSR)) (ite (bveq ((_ extract 3 1) predBits) #b001) (bveq #b1 ((_ extract 29 29) 'CPSR)) (ite (bveq ((_ extract 3 1) predBits) #b010) (bveq #b1 ((_ extract 31 31) 'CPSR)) (ite (bveq ((_ extract 3 1) predBits) #b011) (bveq #b1 ((_ extract 28 28) 'CPSR)) (ite (bveq ((_ extract 3 1) predBits) #b100) (andp (bveq #b1 ((_ extract 29 29) 'CPSR)) (notp (bveq #b1 ((_ extract 30 30) 'CPSR)))) (ite (bveq ((_ extract 3 1) predBits) #b101) (bveq ((_ extract 31 31) 'CPSR) ((_ extract 28 28) 'CPSR)) (ite (bveq ((_ extract 3 1) predBits) #b110) (andp (bveq ((_ extract 31 31) 'CPSR) ((_ extract 28 28) 'CPSR)) (notp (bveq #b1 ((_ extract 30 30) 'CPSR)))) (bveq #b0 #b0))))))))) (ite (bveq ((_ extract 3 1) predBits) #b000) (bveq #b1 ((_ extract 30 30) 'CPSR)) (ite (bveq ((_ extract 3 1) predBits) #b001) (bveq #b1 ((_ extract 29 29) 'CPSR)) (ite (bveq ((_ extract 3 1) predBits) #b010) (bveq #b1 ((_ extract 31 31) 'CPSR)) (ite (bveq ((_ extract 3 1) predBits) #b011) (bveq #b1 ((_ extract 28 28) 'CPSR)) (ite (bveq ((_ extract 3 1) predBits) #b100) (andp (bveq #b1 ((_ extract 29 29) 'CPSR)) (notp (bveq #b1 ((_ extract 30 30) 'CPSR)))) (ite (bveq ((_ extract 3 1) predBits) #b101) (bveq ((_ extract 31 31) 'CPSR) ((_ extract 28 28) 'CPSR)) (ite (bveq ((_ extract 3 1) predBits) #b110) (andp (bveq ((_ extract 31 31) 'CPSR) ((_ extract 28 28) 'CPSR)) (notp (bveq #b1 ((_ extract 30 30) 'CPSR)))) (bveq #b0 #b0))))))))) (ite (andp (bveq setcc #b1) (notp ((_ call "arm.is_r15") rD))) (concat (concat ((_ extract 31 31) ((_ extract 31 0) (bvadd (bvadd ((_ zero_extend 1) rN) ((_ zero_extend 1) (ite (bveq (bvshl #x00000001 ((_ zero_extend 28) ((_ call "a32.modimm_rot") mimm))) #x00000000) ((_ zero_extend 24) ((_ call "a32.modimm_imm") mimm)) (bvor (bvshl (bvshl #x00000001 ((_ zero_extend 28) ((_ call "a32.modimm_rot") mimm))) (bvsub #x00000020 (bvurem ((_ zero_extend 24) ((_ call "a32.modimm_imm") mimm)) #x00000020))) (bvlshr (bvshl #x00000001 ((_ zero_extend 28) ((_ call "a32.modimm_rot") mimm))) (bvurem ((_ zero_extend 24) ((_ call "a32.modimm_imm") mimm)) #x00000020)))))) ((_ zero_extend 1) #x00000000)))) (concat (ite (bveq ((_ extract 31 0) (bvadd (bvadd ((_ zero_extend 1) rN) ((_ zero_extend 1) (ite (bveq (bvshl #x00000001 ((_ zero_extend 28) ((_ call "a32.modimm_rot") mimm))) #x00000000) ((_ zero_extend 24) ((_ call "a32.modimm_imm") mimm)) (bvor (bvshl (bvshl #x00000001 ((_ zero_extend 28) ((_ call "a32.modimm_rot") mimm))) (bvsub #x00000020 (bvurem ((_ zero_extend 24) ((_ call "a32.modimm_imm") mimm)) #x00000020))) (bvlshr (bvshl #x00000001 ((_ zero_extend 28) ((_ call "a32.modimm_rot") mimm))) (bvurem ((_ zero_extend 24) ((_ call "a32.modimm_imm") mimm)) #x00000020)))))) ((_ zero_extend 1) #x00000000))) #x00000000) #b1 #b0) (concat ((_ extract 32 32) (bvadd (bvadd ((_ zero_extend 1) rN) ((_ zero_extend 1) (ite (bveq (bvshl #x00000001 ((_ zero_extend 28) ((_ call "a32.modimm_rot") mimm))) #x00000000) ((_ zero_extend 24) ((_ call "a32.modimm_imm") mimm)) (bvor (bvshl (bvshl #x00000001 ((_ zero_extend 28) ((_ call "a32.modimm_rot") mimm))) (bvsub #x00000020 (bvurem ((_ zero_extend 24) ((_ call "a32.modimm_imm") mimm)) #x00000020))) (bvlshr (bvshl #x00000001 ((_ zero_extend 28) ((_ call "a32.modimm_rot") mimm))) (bvurem ((_ zero_extend 24) ((_ call "a32.modimm_imm") mimm)) #x00000020)))))) ((_ zero_extend 1) #x00000000))) (bvand ((_ extract 31 31) ((_ extract 31 0) (bvadd (bvadd ((_ zero_extend 1) rN) ((_ zero_extend 1) (ite (bveq (bvshl #x00000001 ((_ zero_extend 28) ((_ call "a32.modimm_rot") mimm))) #x00000000) ((_ zero_extend 24) ((_ call "a32.modimm_imm") mimm)) (bvor (bvshl (bvshl #x00000001 ((_ zero_extend 28) ((_ call "a32.modimm_rot") mimm))) (bvsub #x00000020 (bvurem ((_ zero_extend 24) ((_ call "a32.modimm_imm") mimm)) #x00000020))) (bvlshr (bvshl #x00000001 ((_ zero_extend 28) ((_ call "a32.modimm_rot") mimm))) (bvurem ((_ zero_extend 24) ((_ call "a32.modimm_imm") mimm)) #x00000020)))))) ((_ zero_extend 1) #x00000000)))) ((_ extract 32 32) (bvadd (bvadd ((_ zero_extend 1) rN) ((_ zero_extend 1) (ite (bveq (bvshl #x00000001 ((_ zero_extend 28) ((_ call "a32.modimm_rot") mimm))) #x00000000) ((_ zero_extend 24) ((_ call "a32.modimm_imm") mimm)) (bvor (bvshl (bvshl #x00000001 ((_ zero_extend 28) ((_ call "a32.modimm_rot") mimm))) (bvsub #x00000020 (bvurem ((_ zero_extend 24) ((_ call "a32.modimm_imm") mimm)) #x00000020))) (bvlshr (bvshl #x00000001 ((_ zero_extend 28) ((_ call "a32.modimm_rot") mimm))) (bvurem ((_ zero_extend 24) ((_ call "a32.modimm_imm") mimm)) #x00000020)))))) ((_ zero_extend 1) #x00000000))))))) ((_ extract 27 0) (ite ((_ call "arm.is_r15") rD) (ite (bveq #b0 ((_ extract 0 0) ((_ extract 31 0) (bvadd (bvadd ((_ zero_extend 1) rN) ((_ zero_extend 1) (ite (bveq (bvshl #x00000001 ((_ zero_extend 28) ((_ call "a32.modimm_rot") mimm))) #x00000000) ((_ zero_extend 24) ((_ call "a32.modimm_imm") mimm)) (bvor (bvshl (bvshl #x00000001 ((_ zero_extend 28) ((_ call "a32.modimm_rot") mimm))) (bvsub #x00000020 (bvurem ((_ zero_extend 24) ((_ call "a32.modimm_imm") mimm)) #x00000020))) (bvlshr (bvshl #x00000001 ((_ zero_extend 28) ((_ call "a32.modimm_rot") mimm))) (bvurem ((_ zero_extend 24) ((_ call "a32.modimm_imm") mimm)) #x00000020)))))) ((_ zero_extend 1) #x00000000))))) (bvand #xfeffffff (bvor #x00000020 'CPSR)) 'CPSR) 'CPSR))) (ite ((_ call "arm.is_r15") rD) (ite (bveq #b0 ((_ extract 0 0) ((_ extract 31 0) (bvadd (bvadd ((_ zero_extend 1) rN) ((_ zero_extend 1) (ite (bveq (bvshl #x00000001 ((_ zero_extend 28) ((_ call "a32.modimm_rot") mimm))) #x00000000) ((_ zero_extend 24) ((_ call "a32.modimm_imm") mimm)) (bvor (bvshl (bvshl #x00000001 ((_ zero_extend 28) ((_ call "a32.modimm_rot") mimm))) (bvsub #x00000020 (bvurem ((_ zero_extend 24) ((_ call "a32.modimm_imm") mimm)) #x00000020))) (bvlshr (bvshl #x00000001 ((_ zero_extend 28) ((_ call "a32.modimm_rot") mimm))) (bvurem ((_ zero_extend 24) ((_ call "a32.modimm_imm") mimm)) #x00000020)))))) ((_ zero_extend 1) #x00000000))))) (bvand #xfeffffff (bvor #x00000020 'CPSR)) 'CPSR) 'CPSR)) 'CPSR)) (rD (ite (ite (andp (bveq #b1 ((_ extract 0 0) predBits)) (bvne predBits #xf)) (notp (ite (bveq ((_ extract 3 1) predBits) #b000) (bveq #b1 ((_ extract 30 30) 'CPSR)) (ite (bveq ((_ extract 3 1) predBits) #b001) (bveq #b1 ((_ extract 29 29) 'CPSR)) (ite (bveq ((_ extract 3 1) predBits) #b010) (bveq #b1 ((_ extract 31 31) 'CPSR)) (ite (bveq ((_ extract 3 1) predBits) #b011) (bveq #b1 ((_ extract 28 28) 'CPSR)) (ite (bveq ((_ extract 3 1) predBits) #b100) (andp (bveq #b1 ((_ extract 29 29) 'CPSR)) (notp (bveq #b1 ((_ extract 30 30) 'CPSR)))) (ite (bveq ((_ extract 3 1) predBits) #b101) (bveq ((_ extract 31 31) 'CPSR) ((_ extract 28 28) 'CPSR)) (ite (bveq ((_ extract 3 1) predBits) #b110) (andp (bveq ((_ extract 31 31) 'CPSR) ((_ extract 28 28) 'CPSR)) (notp (bveq #b1 ((_ extract 30 30) 'CPSR)))) (bveq #b0 #b0))))))))) (ite (bveq ((_ extract 3 1) predBits) #b000) (bveq #b1 ((_ extract 30 30) 'CPSR)) (ite (bveq ((_ extract 3 1) predBits) #b001) (bveq #b1 ((_ extract 29 29) 'CPSR)) (ite (bveq ((_ extract 3 1) predBits) #b010) (bveq #b1 ((_ extract 31 31) 'CPSR)) (ite (bveq ((_ extract 3 1) predBits) #b011) (bveq #b1 ((_ extract 28 28) 'CPSR)) (ite (bveq ((_ extract 3 1) predBits) #b100) (andp (bveq #b1 ((_ extract 29 29) 'CPSR)) (notp (bveq #b1 ((_ extract 30 30) 'CPSR)))) (ite (bveq ((_ extract 3 1) predBits) #b101) (bveq ((_ extract 31 31) 'CPSR) ((_ extract 28 28) 'CPSR)) (ite (bveq ((_ extract 3 1) predBits) #b110) (andp (bveq ((_ extract 31 31) 'CPSR) ((_ extract 28 28) 'CPSR)) (notp (bveq #b1 ((_ extract 30 30) 'CPSR)))) (bveq #b0 #b0))))))))) (ite ((_ call "arm.is_r15") rD) rD ((_ extract 31 0) (bvadd (bvadd ((_ zero_extend 1) rN) ((_ zero_extend 1) (ite (bveq (bvshl #x00000001 ((_ zero_extend 28) ((_ call "a32.modimm_rot") mimm))) #x00000000) ((_ zero_extend 24) ((_ call "a32.modimm_imm") mimm)) (bvor (bvshl (bvshl #x00000001 ((_ zero_extend 28) ((_ call "a32.modimm_rot") mimm))) (bvsub #x00000020 (bvurem ((_ zero_extend 24) ((_ call "a32.modimm_imm") mimm)) #x00000020))) (bvlshr (bvshl #x00000001 ((_ zero_extend 28) ((_ call "a32.modimm_rot") mimm))) (bvurem ((_ zero_extend 24) ((_ call "a32.modimm_imm") mimm)) #x00000020)))))) ((_ zero_extend 1) #x00000000)))) rD)))))
diff --git a/test/med-sample.sexp b/test/med-sample.sexp
new file mode 100644
--- /dev/null
+++ b/test/med-sample.sexp
@@ -0,0 +1,17 @@
+((operands ((rA . 'Gprc) (rS . 'Gprc) (rB . 'Gprc))) 
+  (in ('XER 'CR rB rS 'IP))
+  (defs 
+    (('CR 
+       (bvor 
+         (bvand 
+           'CR
+           (bvnot (bvshl #x0000000f (bvmul ((_ zero_extend 29) #b000) #x00000004))))
+         (bvshl 
+           ((_ zero_extend 28) 
+             (concat 
+               (ite 
+                 (bvslt (bvxor rS rB) #x00000000)
+                 #b100
+                 (ite (bvsgt (bvxor rS rB) #x00000000) #b010 #b001))
+               ((_ extract 0 0) 'XER)))
+           (bvmul ((_ zero_extend 29) #b000) #x00000004)))) (rA (bvxor rS rB)) ('IP (bvadd 'IP #x00000004)))))
diff --git a/test/med2-sample.sexp b/test/med2-sample.sexp
new file mode 100644
--- /dev/null
+++ b/test/med2-sample.sexp
@@ -0,0 +1,262 @@
+((operands
+ ((rD . 'GPR)
+ (setcc . 'Cc_out)
+ (predBits . 'Pred)
+ (rM . 'GPR)
+ (rN . 'GPR)))
+(in (setcc rN rM 'CPSR 'PC))
+(defs
+ (('PC
+  (ite
+   ((_ call "arm.is_r15") rD)
+   (ite
+    (bveq
+     #b0
+     ((_ extract 0 0)
+     ((_ extract 31 0)
+     (bvadd
+      (bvadd ((_ zero_extend 1) rN) ((_ zero_extend 1) (bvnot rM)))
+      ((_ zero_extend 1) #x00000001)))))
+    (bvand
+     #xfffffffe
+     ((_ extract 31 0)
+     (bvadd
+      (bvadd ((_ zero_extend 1) rN) ((_ zero_extend 1) (bvnot rM)))
+      ((_ zero_extend 1) #x00000001))))
+    (ite
+     (bveq
+      #b0
+      ((_ extract 1 1)
+      ((_ extract 31 0)
+      (bvadd
+       (bvadd
+        ((_ zero_extend 1) rN)
+        ((_ zero_extend 1) (bvnot rM)))
+       ((_ zero_extend 1) #x00000001)))))
+     (bvand
+      #xfffffffd
+      ((_ extract 31 0)
+      (bvadd
+       (bvadd
+        ((_ zero_extend 1) rN)
+        ((_ zero_extend 1) (bvnot rM)))
+       ((_ zero_extend 1) #x00000001))))
+     ((_ extract 31 0)
+     (bvadd
+      (bvadd ((_ zero_extend 1) rN) ((_ zero_extend 1) (bvnot rM)))
+      ((_ zero_extend 1) #x00000001)))))
+   (bvadd 'PC #x00000004)))
+ ('CPSR
+  (ite
+   (ite
+    (andp (bveq #b1 ((_ extract 0 0) predBits)) (bvne predBits #xf))
+    (notp
+     (ite
+      (bveq ((_ extract 3 1) predBits) #b000)
+      (bveq #b1 ((_ extract 30 30) 'CPSR))
+      (ite
+       (bveq ((_ extract 3 1) predBits) #b001)
+       (bveq #b1 ((_ extract 29 29) 'CPSR))
+       (ite
+        (bveq ((_ extract 3 1) predBits) #b010)
+        (bveq #b1 ((_ extract 31 31) 'CPSR))
+        (ite
+         (bveq ((_ extract 3 1) predBits) #b011)
+         (bveq #b1 ((_ extract 28 28) 'CPSR))
+         (ite
+          (bveq ((_ extract 3 1) predBits) #b100)
+          (andp
+           (bveq #b1 ((_ extract 29 29) 'CPSR))
+           (notp (bveq #b1 ((_ extract 30 30) 'CPSR))))
+          (ite
+           (bveq ((_ extract 3 1) predBits) #b101)
+           (bveq
+            ((_ extract 31 31) 'CPSR)
+            ((_ extract 28 28) 'CPSR))
+           (ite
+            (bveq ((_ extract 3 1) predBits) #b110)
+            (andp
+             (bveq
+              ((_ extract 31 31) 'CPSR)
+              ((_ extract 28 28) 'CPSR))
+             (notp (bveq #b1 ((_ extract 30 30) 'CPSR))))
+            (bveq #b0 #b0)))))))))
+    (ite
+     (bveq ((_ extract 3 1) predBits) #b000)
+     (bveq #b1 ((_ extract 30 30) 'CPSR))
+     (ite
+      (bveq ((_ extract 3 1) predBits) #b001)
+      (bveq #b1 ((_ extract 29 29) 'CPSR))
+      (ite
+       (bveq ((_ extract 3 1) predBits) #b010)
+       (bveq #b1 ((_ extract 31 31) 'CPSR))
+       (ite
+        (bveq ((_ extract 3 1) predBits) #b011)
+        (bveq #b1 ((_ extract 28 28) 'CPSR))
+        (ite
+         (bveq ((_ extract 3 1) predBits) #b100)
+         (andp
+          (bveq #b1 ((_ extract 29 29) 'CPSR))
+          (notp (bveq #b1 ((_ extract 30 30) 'CPSR))))
+         (ite
+          (bveq ((_ extract 3 1) predBits) #b101)
+          (bveq
+           ((_ extract 31 31) 'CPSR)
+           ((_ extract 28 28) 'CPSR))
+          (ite
+           (bveq ((_ extract 3 1) predBits) #b110)
+           (andp
+            (bveq
+             ((_ extract 31 31) 'CPSR)
+             ((_ extract 28 28) 'CPSR))
+            (notp (bveq #b1 ((_ extract 30 30) 'CPSR))))
+           (bveq #b0 #b0)))))))))
+   (ite
+    (andp (bveq setcc #b1) (notp ((_ call "arm.is_r15") rD)))
+    (concat
+     (concat
+      ((_ extract 31 31)
+      ((_ extract 31 0)
+      (bvadd
+       (bvadd
+        ((_ zero_extend 1) rN)
+        ((_ zero_extend 1) (bvnot rM)))
+       ((_ zero_extend 1) #x00000001))))
+      (concat
+       (ite
+        (bveq
+         ((_ extract 31 0)
+         (bvadd
+          (bvadd
+           ((_ zero_extend 1) rN)
+           ((_ zero_extend 1) (bvnot rM)))
+          ((_ zero_extend 1) #x00000001)))
+         #x00000000)
+        #b1
+        #b0)
+       (concat
+        ((_ extract 32 32)
+        (bvadd
+         (bvadd
+          ((_ zero_extend 1) rN)
+          ((_ zero_extend 1) (bvnot rM)))
+         ((_ zero_extend 1) #x00000001)))
+        (bvand
+         ((_ extract 31 31)
+         ((_ extract 31 0)
+         (bvadd
+          (bvadd
+           ((_ zero_extend 1) rN)
+           ((_ zero_extend 1) (bvnot rM)))
+          ((_ zero_extend 1) #x00000001))))
+         ((_ extract 32 32)
+         (bvadd
+          (bvadd
+           ((_ zero_extend 1) rN)
+           ((_ zero_extend 1) (bvnot rM)))
+          ((_ zero_extend 1) #x00000001)))))))
+     ((_ extract 27 0)
+     (ite
+      ((_ call "arm.is_r15") rD)
+      (ite
+       (bveq
+        #b0
+        ((_ extract 0 0)
+        ((_ extract 31 0)
+        (bvadd
+         (bvadd
+          ((_ zero_extend 1) rN)
+          ((_ zero_extend 1) (bvnot rM)))
+         ((_ zero_extend 1) #x00000001)))))
+       (bvand #xfeffffff (bvor #x00000020 'CPSR))
+       'CPSR)
+      'CPSR)))
+    (ite
+     ((_ call "arm.is_r15") rD)
+     (ite
+      (bveq
+       #b0
+       ((_ extract 0 0)
+       ((_ extract 31 0)
+       (bvadd
+        (bvadd
+         ((_ zero_extend 1) rN)
+         ((_ zero_extend 1) (bvnot rM)))
+        ((_ zero_extend 1) #x00000001)))))
+      (bvand #xfeffffff (bvor #x00000020 'CPSR))
+      'CPSR)
+     'CPSR))
+   'CPSR))
+ (rD
+  (ite
+   (ite
+    (andp (bveq #b1 ((_ extract 0 0) predBits)) (bvne predBits #xf))
+    (notp
+     (ite
+      (bveq ((_ extract 3 1) predBits) #b000)
+      (bveq #b1 ((_ extract 30 30) 'CPSR))
+      (ite
+       (bveq ((_ extract 3 1) predBits) #b001)
+       (bveq #b1 ((_ extract 29 29) 'CPSR))
+       (ite
+        (bveq ((_ extract 3 1) predBits) #b010)
+        (bveq #b1 ((_ extract 31 31) 'CPSR))
+        (ite
+         (bveq ((_ extract 3 1) predBits) #b011)
+         (bveq #b1 ((_ extract 28 28) 'CPSR))
+         (ite
+          (bveq ((_ extract 3 1) predBits) #b100)
+          (andp
+           (bveq #b1 ((_ extract 29 29) 'CPSR))
+           (notp (bveq #b1 ((_ extract 30 30) 'CPSR))))
+          (ite
+           (bveq ((_ extract 3 1) predBits) #b101)
+           (bveq
+            ((_ extract 31 31) 'CPSR)
+            ((_ extract 28 28) 'CPSR))
+           (ite
+            (bveq ((_ extract 3 1) predBits) #b110)
+            (andp
+             (bveq
+              ((_ extract 31 31) 'CPSR)
+              ((_ extract 28 28) 'CPSR))
+             (notp (bveq #b1 ((_ extract 30 30) 'CPSR))))
+            (bveq #b0 #b0)))))))))
+    (ite
+     (bveq ((_ extract 3 1) predBits) #b000)
+     (bveq #b1 ((_ extract 30 30) 'CPSR))
+     (ite
+      (bveq ((_ extract 3 1) predBits) #b001)
+      (bveq #b1 ((_ extract 29 29) 'CPSR))
+      (ite
+       (bveq ((_ extract 3 1) predBits) #b010)
+       (bveq #b1 ((_ extract 31 31) 'CPSR))
+       (ite
+        (bveq ((_ extract 3 1) predBits) #b011)
+        (bveq #b1 ((_ extract 28 28) 'CPSR))
+        (ite
+         (bveq ((_ extract 3 1) predBits) #b100)
+         (andp
+          (bveq #b1 ((_ extract 29 29) 'CPSR))
+          (notp (bveq #b1 ((_ extract 30 30) 'CPSR))))
+         (ite
+          (bveq ((_ extract 3 1) predBits) #b101)
+          (bveq
+           ((_ extract 31 31) 'CPSR)
+           ((_ extract 28 28) 'CPSR))
+          (ite
+           (bveq ((_ extract 3 1) predBits) #b110)
+           (andp
+            (bveq
+             ((_ extract 31 31) 'CPSR)
+             ((_ extract 28 28) 'CPSR))
+            (notp (bveq #b1 ((_ extract 30 30) 'CPSR))))
+           (bveq #b0 #b0)))))))))
+   (ite
+    ((_ call "arm.is_r15") rD)
+    rD
+    ((_ extract 31 0)
+    (bvadd
+     (bvadd ((_ zero_extend 1) rN) ((_ zero_extend 1) (bvnot rM)))
+     ((_ zero_extend 1) #x00000001))))
+   rD)))))
diff --git a/test/small-sample.sexp b/test/small-sample.sexp
new file mode 100644
--- /dev/null
+++ b/test/small-sample.sexp
@@ -0,0 +1,1 @@
+((operands ((rT . 'Gprc) (rA . 'Gprc))) (in (rA 'IP)) (defs ((rT rA) ('IP (bvadd 'IP #x00000004)))))
