{-# LANGUAGE DeriveGeneric, DefaultSignatures, StrictData, StandaloneDeriving, BangPatterns #-}

{-|
Module      : SValue
Description : 
-}

module Data.SValue where

import Data.SymbolicExpression

import Base

import qualified Data.Map as M
import qualified Data.Set as S
import qualified Data.IntMap as IM
import qualified Data.IntSet as IS
import Data.Word 
import Data.List
import GHC.Generics
import qualified Data.Serialize as Cereal
import Data.Bits (testBit)
import qualified Data.Set.NonEmpty as NES
import qualified Data.Foldable as F
import Control.DeepSeq




data SValue = SConcrete (NES.NESet SimpleExpr) | SAddends (NES.NESet SimpleExpr) | Top
 deriving ((forall x. SValue -> Rep SValue x)
-> (forall x. Rep SValue x -> SValue) -> Generic SValue
forall x. Rep SValue x -> SValue
forall x. SValue -> Rep SValue x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. SValue -> Rep SValue x
from :: forall x. SValue -> Rep SValue x
$cto :: forall x. Rep SValue x -> SValue
to :: forall x. Rep SValue x -> SValue
Generic,SValue -> SValue -> Bool
(SValue -> SValue -> Bool)
-> (SValue -> SValue -> Bool) -> Eq SValue
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: SValue -> SValue -> Bool
== :: SValue -> SValue -> Bool
$c/= :: SValue -> SValue -> Bool
/= :: SValue -> SValue -> Bool
Eq,Eq SValue
Eq SValue =>
(SValue -> SValue -> Ordering)
-> (SValue -> SValue -> Bool)
-> (SValue -> SValue -> Bool)
-> (SValue -> SValue -> Bool)
-> (SValue -> SValue -> Bool)
-> (SValue -> SValue -> SValue)
-> (SValue -> SValue -> SValue)
-> Ord SValue
SValue -> SValue -> Bool
SValue -> SValue -> Ordering
SValue -> SValue -> SValue
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: SValue -> SValue -> Ordering
compare :: SValue -> SValue -> Ordering
$c< :: SValue -> SValue -> Bool
< :: SValue -> SValue -> Bool
$c<= :: SValue -> SValue -> Bool
<= :: SValue -> SValue -> Bool
$c> :: SValue -> SValue -> Bool
> :: SValue -> SValue -> Bool
$c>= :: SValue -> SValue -> Bool
>= :: SValue -> SValue -> Bool
$cmax :: SValue -> SValue -> SValue
max :: SValue -> SValue -> SValue
$cmin :: SValue -> SValue -> SValue
min :: SValue -> SValue -> SValue
Ord)



-- | A `symbolic value` is either a `pointer value` (high certainty that it is actually a pointer),
-- or a non-deterministic set of concrete expressions, or computed from a set of possible addends.
--data SValue      = SPointer (NES.NESet PtrValue) | SConcrete (NES.NESet SimpleExpr) | SAddends (NES.NESet SAddend) | Top
--  deriving (Eq,Ord,Generic)

instance Cereal.Serialize SValue
instance NFData SValue
  

instance Show SValue where
  show :: SValue -> String
show SValue
Top             = String
"top" 
  show (SConcrete NESet SimpleExpr
es) 
    | NESet SimpleExpr -> Int
forall a. NESet a -> Int
NES.size NESet SimpleExpr
es Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
1 = SimpleExpr -> String
forall a. Show a => a -> String
show (SimpleExpr -> String) -> SimpleExpr -> String
forall a b. (a -> b) -> a -> b
$ NESet SimpleExpr -> SimpleExpr
forall a. NESet a -> a
NES.findMin NESet SimpleExpr
es 
    | Bool
otherwise        = [SimpleExpr] -> String
forall (t :: * -> *) a. (Foldable t, Show a) => t a -> String
show_set ([SimpleExpr] -> String) -> [SimpleExpr] -> String
forall a b. (a -> b) -> a -> b
$ NESet SimpleExpr -> [SimpleExpr]
forall {a}. NESet a -> [a]
neSetToList NESet SimpleExpr
es
  show (SAddends NESet SimpleExpr
adds) = String
"{" String -> ShowS
forall a. [a] -> [a] -> [a]
++ (String -> [String] -> String
forall a. [a] -> [[a]] -> [a]
intercalate String
"," ([String] -> String) -> [String] -> String
forall a b. (a -> b) -> a -> b
$ (SimpleExpr -> String) -> [SimpleExpr] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map SimpleExpr -> String
forall a. Show a => a -> String
show_adds ([SimpleExpr] -> [String]) -> [SimpleExpr] -> [String]
forall a b. (a -> b) -> a -> b
$ NESet SimpleExpr -> [SimpleExpr]
forall {a}. NESet a -> [a]
neSetToList NESet SimpleExpr
adds) String -> ShowS
forall a. [a] -> [a] -> [a]
++String
"}"
   where
    show_adds :: a -> String
show_adds a
a = String
"(" String -> ShowS
forall a. [a] -> [a] -> [a]
++ a -> String
forall a. Show a => a -> String
show a
a String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"+..)"