packages feed

s-cargot 0.1.3.0 → 0.1.4.0

raw patch · 8 files changed

+681/−44 lines, 8 filesdep +HUnitPVP ok

version bump matches the API change (PVP)

Dependencies added: HUnit

API changes (from Hackage documentation)

+ Data.SCargot.Print: encodeLazy :: SExprPrinter atom carrier -> [carrier] -> Text
+ Data.SCargot.Print: encodeOneLazy :: SExprPrinter atom carrier -> carrier -> Text
+ Data.SCargot.Print: instance GHC.Show.Show Data.SCargot.Print.Size

Files

CHANGELOG.md view
@@ -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 ======= 
Data/SCargot/Print.hs view
@@ -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)
s-cargot.cabal view
@@ -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
+ test/SCargotPrintParse.hs view
@@ -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
+ test/big-sample.sexp view
@@ -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)))))
+ test/med-sample.sexp view
@@ -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)))))
+ test/med2-sample.sexp view
@@ -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)))))
+ test/small-sample.sexp view
@@ -0,0 +1,1 @@+((operands ((rT . 'Gprc) (rA . 'Gprc))) (in (rA 'IP)) (defs ((rT rA) ('IP (bvadd 'IP #x00000004)))))