module Language.Floorplan.Rust.Common
where
import Language.Rust.Parser as P
import Language.Rust.Syntax as R
import Language.Rust.Quote
import Language.Rust.Data.Ident
import Language.Rust.Data.Position
import Language.Floorplan.Core.Syntax
import Data.Functor ( ($>) )
import Data.Ord (comparing)
import Data.List (sortBy, nub)
import Data.Char (toUpper, toLower)
import Language.Floorplan.Rust.Types
import qualified Debug.Trace as D
bytesInWord :: Int
bytesInWord = 8
bitsInByte :: Int
bitsInByte = 8
isPow2 k = elem k $ map (2 ^) [0..k]
log' :: Int -> Int -> Int
log' i n = length (takeWhile (< n) (iterate (* 2) 1))
log2 :: Int -> Int
log2 = log' 2
fakeSpan = Span (Position 0 0 0) (Position 0 0 0)
fS = fakeSpan
mkIntExp :: Int -> R.Expr Span
mkIntExp i = P.parse' $ P.inputStreamFromString $ show i
mkBin' i
| i == 0 = []
| i `mod` 2 == 0 = '0' : mkBin' (i `div` 2)
| i `mod` 2 == 1 = '1' : mkBin' (i `div` 2)
mkBinU8 i
| i >= 256 = error $ "Cannot make u8 from i=" ++ show i
| otherwise = take (8 - (length $ mkBin' i)) (repeat '0') ++ (reverse $ mkBin' i)
mkBinExp :: Int -> R.Expr Span
mkBinExp i = P.parse' $ P.inputStreamFromString $ "0b" ++ mkBinU8 i
offsetName :: NameID -> String
offsetName n
= allUpper n ++ "_OFFSET_BYTES"
containsFnName :: NameID -> String
containsFnName ns
= "contains_" ++ firstLower ns
firstLower [] = error "empty NameID!"
firstLower (n:ns) = toLower n : ns
firstUpper [] = error "empty NameID!"
firstUpper (n:ns) = toUpper n : ns
allUpper = map toUpper
initSeqName :: [NameID] -> String
initSeqName _ = "init_canonical_sequence"
bumpAllocName :: NameID -> String
bumpAllocName n
= "bump_new_" ++ n
bumpValidName :: NameID -> NameID -> String
bumpValidName n1 n2
= firstLower n1 ++ "_is_validly_before_" ++ firstLower n2
initAfterName :: NameID -> NameID -> String
initAfterName n1 n2
= "init_" ++ firstLower n2 ++ "_after_" ++ firstLower n1
memsetUntilName :: NameID -> NameID -> String
memsetUntilName n1 n2
= "memset_" ++ firstLower n1 ++ "_until_" ++ firstLower n2
castFromName :: NameID -> NameID -> String
castFromName from to
= "cast_" ++ firstLower from ++ "_to_" ++ firstLower to
fromIdxName :: NameID -> String
fromIdxName from
= firstLower from ++ "_from_idx"
toIdxName :: NameID -> String
toIdxName from
= firstLower from ++ "_to_idx"
logBytesName :: NameID -> String
logBytesName n
= "LOG_" ++ bytesName n
bytesName :: NameID -> String
bytesName n
= "BYTES_IN_" ++ allUpper n
addrName xs = firstUpper xs ++ "Addr"
addrEndName n = firstUpper n ++ "AddrEnd"
enumName xs = "__FLP_IDX_" ++ map toUpper xs
structName xs = firstUpper xs
getterName xs = firstLower xs
reverseGetterName xs = "from_" ++ firstLower xs
skipperName ns = "skip_bytes_to_" ++ firstUpper ns
jumperName ns = "jump_to_" ++ firstUpper ns
nextName ns = "next_" ++ firstUpper ns
bitsGetterName sz xs
| sz == 1 = "get_" ++ xs ++ "_bit"
| otherwise = "get_" ++ xs ++ "_bits"
bitsFromerName _ [] = error "empty NameID!"
bitsFromerName sz (x:xs)
| sz == 1 = "set_" ++ x : xs ++ "_from_bool"
| otherwise = "set_" ++ x : xs ++ "_from_u8"
firstGetterName xs = "get_first_" ++ firstLower xs
mkTy :: NameID -> Ty Span
mkTy s = P.parse' $ P.inputStreamFromString s
bytesAlignName n = allUpper n ++ "_BYTES_ALIGN"
logAlignName n = allUpper n ++ "_LOG_BYTES_ALIGN"
fieldPtrGetterName fs = "load_" ++ firstUpper fs ++ "Addr"
fieldPtrSetterName fs = "store_" ++ firstUpper fs ++ "Addr"
fieldStructGetterName fs = "load_" ++ firstUpper fs
fieldStructSetterName fs = "store_" ++ firstUpper fs
findExists :: BaseExp -> [BaseExp]
findExists (Prim{}) = []
findExists (Con _ e) = findExists e
findExists (e :@ _) = findExists e
findExists (_ :+ _) = []
findExists (_ :|| _) = []
findExists (_ ::: _) = []
findExists e@(Exists _ e') = e : findExists e'
findExists (_ :# _) = []
findExists (Attr _ e) = findExists e