Skip to content

Commit 4ba9d09

Browse files
authored
Merge branch 'master' into macaw-264
2 parents da9edfa + e2fef66 commit 4ba9d09

File tree

6 files changed

+63
-0
lines changed

6 files changed

+63
-0
lines changed

saw-core-what4/src/Verifier/SAW/Simulator/What4.hs

+16
Original file line numberDiff line numberDiff line change
@@ -961,6 +961,8 @@ applyUnintApp sym app0 v =
961961
VCtorApp i ps xv -> foldM (applyUnintApp sym) app' =<< traverse force (ps++xv)
962962
where app' = suffixUnintApp ("_" ++ (Text.unpack (identBaseName (primName i)))) app0
963963
VNat n -> return (suffixUnintApp ("_" ++ show n) app0)
964+
VBVToNat w v' -> applyUnintApp sym app' v'
965+
where app' = suffixUnintApp ("_" ++ show w) app0
964966
TValue (suffixTValue -> Just s)
965967
-> return (suffixUnintApp s app0)
966968
VFun _ _ ->
@@ -1399,6 +1401,7 @@ data ArgTerm
13991401
-- ^ length, element type, list, index
14001402
| ArgTermPairLeft ArgTerm
14011403
| ArgTermPairRight ArgTerm
1404+
| ArgTermBVToNat Natural ArgTerm
14021405

14031406
-- | Reassemble a saw-core term from an 'ArgTerm' and a list of parts.
14041407
-- The length of the list should be equal to the number of
@@ -1468,6 +1471,10 @@ reconstructArgTerm atrm sc ts =
14681471
do (x1, ts1) <- parse at1 ts0
14691472
x <- scPairRight sc x1
14701473
return (x, ts1)
1474+
ArgTermBVToNat w at1 ->
1475+
do (x1, ts1) <- parse at1 ts0
1476+
x <- scBvToNat sc w x1
1477+
pure (x, ts1)
14711478

14721479
parseList :: [ArgTerm] -> [Term] -> IO ([Term], [Term])
14731480
parseList [] ts0 = return ([], ts0)
@@ -1519,6 +1526,15 @@ mkArgTerm sc ty val =
15191526
do x <- termOfTValue sc tval
15201527
pure (ArgTermConst x)
15211528

1529+
(_, VNat n) ->
1530+
do x <- scNat sc n
1531+
pure (ArgTermConst x)
1532+
1533+
(_, VBVToNat w v) ->
1534+
do let w' = fromIntegral w -- FIXME: make w :: Natural to avoid fromIntegral
1535+
x <- mkArgTerm sc (VVecType w' VBoolType) v
1536+
pure (ArgTermBVToNat w' x)
1537+
15221538
_ -> fail $ "could not create uninterpreted function argument of type " ++ show ty
15231539

15241540
termOfTValue :: SharedContext -> TValue (What4 sym) -> IO Term

saw-core/src/Verifier/SAW/Grammar.y

+2
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ import Verifier.SAW.Lexer
8080
'injectCode' { PosPair _ (TKey "injectCode") }
8181

8282
nat { PosPair _ (TNat _) }
83+
bvlit { PosPair _ (TBitvector _) }
8384
'_' { PosPair _ (TIdent "_") }
8485
ident { PosPair _ (TIdent _) }
8586
identrec { PosPair _ (TRecursor _) }
@@ -177,6 +178,7 @@ AppTerm : AtomTerm { $1 }
177178
AtomTerm :: { Term }
178179
AtomTerm
179180
: nat { NatLit (pos $1) (tokNat (val $1)) }
181+
| bvlit { BVLit (pos $1) (tokBits (val $1)) }
180182
| string { StringLit (pos $1) (Text.pack (tokString (val $1))) }
181183
| Ident { Name $1 }
182184
| IdentRec { Recursor Nothing $1 }

saw-core/src/Verifier/SAW/Lexer.x

+17
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ import Control.Monad.State.Strict
3737
import qualified Data.ByteString.Lazy as B
3838
import Data.ByteString.Lazy.UTF8 (toString)
3939
import Data.Word (Word8)
40+
import Data.Bits
41+
import Data.Char (digitToInt)
4042
import Numeric.Natural
4143

4244
import Verifier.SAW.Position
@@ -86,6 +88,8 @@ $white+;
8688
"-}" { \_ -> TCmntE }
8789
\" @string* \" { TString . read }
8890
@num { TNat . read }
91+
"0x"@hex { TBitvector . readHexBV . drop 2 }
92+
"0b"[0-1]+ { TBitvector . readBinBV . drop 2 }
8993
@key { TKey }
9094
@ident { TIdent }
9195
@ident "#rec" { TRecursor . dropRecSuffix }
@@ -96,6 +100,7 @@ data Token
96100
= TIdent { tokIdent :: String } -- ^ Identifier
97101
| TRecursor { tokRecursor :: String } -- ^ Recursor
98102
| TNat { tokNat :: Natural } -- ^ Natural number literal
103+
| TBitvector { tokBits :: [Bool] } -- ^ Bitvector literal
99104
| TString { tokString :: String } -- ^ String literal
100105
| TKey String -- ^ Keyword or predefined symbol
101106
| TEnd -- ^ End of file.
@@ -108,12 +113,24 @@ data Token
108113
dropRecSuffix :: String -> String
109114
dropRecSuffix str = take (length str - 4) str
110115
116+
-- | Convert a hexadecimal string to a big endian list of bits
117+
readHexBV :: String -> [Bool]
118+
readHexBV =
119+
concatMap (\c -> let i = digitToInt c in
120+
[testBit i 3, testBit i 2, testBit i 1, testBit i 0])
121+
122+
-- | Convert a binary string to a big endian list of bits
123+
readBinBV :: String -> [Bool]
124+
readBinBV = map (\c -> c == '1')
125+
111126
ppToken :: Token -> String
112127
ppToken tkn =
113128
case tkn of
114129
TIdent s -> s
115130
TRecursor s -> s ++ "#rec"
116131
TNat n -> show n
132+
TBitvector bits ->
133+
"0b" ++ map (\b -> if b then '1' else '0') bits
117134
TString s -> show s
118135
TKey s -> s
119136
TEnd -> "END"

saw-core/src/Verifier/SAW/Term/Pretty.hs

+20
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
{-# LANGUAGE TupleSections #-}
77
{-# LANGUAGE MultiParamTypeClasses #-}
88
{-# LANGUAGE RecordWildCards #-}
9+
{-# LANGUAGE PatternGuards #-}
910

1011
{- |
1112
Module : Verifier.SAW.Term.Pretty
@@ -40,6 +41,7 @@ module Verifier.SAW.Term.Pretty
4041
, ppName
4142
) where
4243

44+
import Data.Char (intToDigit)
4345
import Data.Maybe (isJust)
4446
import Control.Monad.Reader
4547
import Control.Monad.State.Strict as State
@@ -62,6 +64,7 @@ import qualified Data.IntMap.Strict as IntMap
6264
import Verifier.SAW.Name
6365
import Verifier.SAW.Term.Functor
6466
import Verifier.SAW.Utils (panic)
67+
import Verifier.SAW.Recognizer
6568

6669
--------------------------------------------------------------------------------
6770
-- * Doc annotations
@@ -469,11 +472,28 @@ ppFlatTermF prec tf =
469472
RecordProj e fld -> ppProj fld <$> ppTerm' PrecArg e
470473
Sort s h -> return ((if h then pretty ("i"::String) else mempty) <> viaShow s)
471474
NatLit i -> ppNat <$> (ppOpts <$> ask) <*> return (toInteger i)
475+
ArrayValue (asBoolType -> Just _) args
476+
| Just bits <- mapM asBool $ V.toList args ->
477+
if length bits `mod` 4 == 0 then
478+
return $ pretty ("0x" ++ ppBitsToHex bits)
479+
else
480+
return $ pretty ("0b" ++ map (\b -> if b then '1' else '0') bits)
472481
ArrayValue _ args ->
473482
ppArrayValue <$> mapM (ppTerm' PrecTerm) (V.toList args)
474483
StringLit s -> return $ viaShow s
475484
ExtCns cns -> annotate ExtCnsStyle <$> ppBestName (ecName cns)
476485

486+
-- | Pretty-print a big endian list of bit values as a hexadecimal number
487+
ppBitsToHex :: [Bool] -> String
488+
ppBitsToHex (b8:b4:b2:b1:bits') =
489+
intToDigit (8 * toInt b8 + 4 * toInt b4 + 2 * toInt b2 + toInt b1) :
490+
ppBitsToHex bits'
491+
where toInt True = 1
492+
toInt False = 0
493+
ppBitsToHex [] = ""
494+
ppBitsToHex bits =
495+
panic "ppBitsToHex" ["length of bit list is not a multiple of 4", show bits]
496+
477497
-- | Pretty-print a name, using the best unambiguous alias from the
478498
-- naming environment.
479499
ppBestName :: NameInfo -> PPM SawDoc

saw-core/src/Verifier/SAW/Typechecker.hs

+5
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,11 @@ typeInferCompleteTerm (Un.VecLit _ ts) =
278278
type_of_tp <- typeInfer tp
279279
typeInferComplete (ArrayValue (TypedTerm tp type_of_tp) $
280280
V.fromList typed_ts)
281+
typeInferCompleteTerm (Un.BVLit _ []) = throwTCError EmptyVectorLit
282+
typeInferCompleteTerm (Un.BVLit _ bits) =
283+
do tp <- liftTCM scBoolType
284+
bit_tms <- mapM (liftTCM scBool) bits
285+
typeInferComplete $ ArrayValue tp $ V.fromList bit_tms
281286

282287
typeInferCompleteTerm (Un.BadTerm _) =
283288
-- Should be unreachable, since BadTerms represent parse errors, that should

saw-core/src/Verifier/SAW/UntypedAST.hs

+3
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,8 @@ data Term
8484
| StringLit Pos Text
8585
-- | Vector literal.
8686
| VecLit Pos [Term]
87+
-- | Bitvector literal.
88+
| BVLit Pos [Bool]
8789
| BadTerm Pos
8890
deriving (Show, TH.Lift)
8991

@@ -128,6 +130,7 @@ instance Positioned Term where
128130
NatLit p _ -> p
129131
StringLit p _ -> p
130132
VecLit p _ -> p
133+
BVLit p _ -> p
131134
BadTerm p -> p
132135

133136
instance Positioned TermVar where

0 commit comments

Comments
 (0)