Generate one file per type, rather than ... quite a few.

This commit is contained in:
2020-03-01 15:51:35 -08:00
parent b995c1705f
commit 71451617f9
18 changed files with 260 additions and 206 deletions

View File

@@ -13,11 +13,11 @@ import CryptoNum(cryptoNum)
import Control.Monad(forM_,unless)
import Data.Text.Lazy(Text, pack)
import Division(divisionOps)
import File(File,Task(..),generateTasks)
import GHC.Conc(getNumCapabilities)
import ModInv(generateModInvOps)
import ModOps(modulusOps)
import Multiply(safeMultiplyOps, unsafeMultiplyOps)
import RustModule(RustModule,Task(..),generateTasks)
import Scale(safeScaleOps, unsafeScaleOps)
import Shift(shiftOps, signedShiftOps)
import Signed(signedBaseOps)
@@ -39,7 +39,7 @@ highestBitsize = 512
bitsizes :: [Word]
bitsizes = [lowestBitsize,lowestBitsize+64..highestBitsize]
unsignedFiles :: [File]
unsignedFiles :: [RustModule]
unsignedFiles = [
base
, binaryOps
@@ -60,7 +60,7 @@ unsignedFiles = [
, unsafeSubtractOps
]
signedFiles :: [File]
signedFiles :: [RustModule]
signedFiles = [
safeSignedAddOps
, safeSignedSubtractOps
@@ -72,7 +72,7 @@ signedFiles = [
, unsafeSignedSubtractOps
]
allFiles :: [File]
allFiles :: [RustModule]
allFiles = unsignedFiles ++ signedFiles
printLast :: Progress String -> Timing -> Text

View File

@@ -37,13 +37,13 @@ library
Conversions,
CryptoNum,
Division,
File,
Gen,
Generators,
Karatsuba,
ModInv,
ModOps,
Multiply,
RustModule,
Scale,
Shift,
Signed,

View File

@@ -10,7 +10,6 @@ module Add(
import Data.Bits((.&.))
import Data.Map.Strict(Map)
import qualified Data.Map.Strict as Map
import File
import Gen(toLit)
import Generators
import Language.Rust.Data.Ident
@@ -19,11 +18,12 @@ import Language.Rust.Quote
import Language.Rust.Syntax
import System.Random(RandomGen)
import RustModule
numTestCases :: Int
numTestCases = 3000
safeAddOps :: File
safeAddOps = File {
safeAddOps :: RustModule
safeAddOps = RustModule {
predicate = \ me others -> (me + 64) `elem` others,
outputName = "safe_add",
isUnsigned = True,
@@ -31,8 +31,8 @@ safeAddOps = File {
testCase = Just generateSafeTests
}
unsafeAddOps :: File
unsafeAddOps = File {
unsafeAddOps :: RustModule
unsafeAddOps = RustModule {
predicate = \ _ _ -> True,
outputName = "unsafe_add",
isUnsigned = True,
@@ -40,8 +40,8 @@ unsafeAddOps = File {
testCase = Just generateUnsafeTests
}
safeSignedAddOps :: File
safeSignedAddOps = File {
safeSignedAddOps :: RustModule
safeSignedAddOps = RustModule {
predicate = \ me others -> (me + 64) `elem` others,
outputName = "safe_sadd",
isUnsigned = False,
@@ -49,8 +49,8 @@ safeSignedAddOps = File {
testCase = Just generateSafeSignedTests
}
unsafeSignedAddOps :: File
unsafeSignedAddOps = File {
unsafeSignedAddOps :: RustModule
unsafeSignedAddOps = RustModule {
predicate = \ _ _ -> True,
outputName = "unsafe_sadd",
isUnsigned = False,

View File

@@ -4,14 +4,14 @@ module Base(
)
where
import File
import Language.Rust.Data.Ident
import Language.Rust.Data.Position
import Language.Rust.Quote
import Language.Rust.Syntax
import RustModule
base :: File
base = File {
base :: RustModule
base = RustModule {
predicate = \ _ _ -> True,
outputName = "base",
isUnsigned = True,

View File

@@ -7,20 +7,20 @@ module BinaryOps(
import Data.Bits(xor,(.&.),(.|.))
import Data.Map.Strict(Map)
import qualified Data.Map.Strict as Map
import File
import Gen(toLit)
import Generators
import Language.Rust.Data.Ident
import Language.Rust.Data.Position
import Language.Rust.Quote
import Language.Rust.Syntax
import RustModule
import System.Random(RandomGen)
numTestCases :: Int
numTestCases = 3000
binaryOps :: File
binaryOps = File {
binaryOps :: RustModule
binaryOps = RustModule {
predicate = \ _ _ -> True,
outputName = "binary",
isUnsigned = True,

View File

@@ -4,19 +4,19 @@ module Compare(comparisons, signedComparisons)
import Data.Map.Strict(Map)
import qualified Data.Map.Strict as Map
import File
import Generators
import Language.Rust.Data.Ident
import Language.Rust.Data.Position
import Language.Rust.Quote
import Language.Rust.Syntax
import RustModule
import System.Random(RandomGen)
numTestCases :: Int
numTestCases = 3000
comparisons :: File
comparisons = File {
comparisons :: RustModule
comparisons = RustModule {
predicate = \ _ _ -> True,
outputName = "compare",
isUnsigned = True,
@@ -24,8 +24,8 @@ comparisons = File {
testCase = Just generateTests
}
signedComparisons :: File
signedComparisons = File {
signedComparisons :: RustModule
signedComparisons = RustModule {
predicate = \ _ _ -> True,
outputName = "scompare",
isUnsigned = False,

View File

@@ -5,15 +5,15 @@ module Conversions(
)
where
import File
import Gen(toLit)
import Language.Rust.Data.Ident
import Language.Rust.Data.Position
import Language.Rust.Quote
import Language.Rust.Syntax
import RustModule
conversions :: File
conversions = File {
conversions :: RustModule
conversions = RustModule {
predicate = \ _ _ -> True,
outputName = "conversions",
isUnsigned = True,
@@ -21,8 +21,8 @@ conversions = File {
testCase = Nothing
}
signedConversions :: File
signedConversions = File {
signedConversions :: RustModule
signedConversions = RustModule {
predicate = \ _ _ -> True,
outputName = "sconversions",
isUnsigned = False,

View File

@@ -7,20 +7,20 @@ module CryptoNum(
import Data.Bits(testBit)
import Data.Map.Strict(Map)
import qualified Data.Map.Strict as Map
import File
import Gen
import Generators
import Language.Rust.Data.Ident
import Language.Rust.Data.Position
import Language.Rust.Quote
import Language.Rust.Syntax
import RustModule
import System.Random(RandomGen)
numTestCases :: Int
numTestCases = 3000
cryptoNum :: File
cryptoNum = File {
cryptoNum :: RustModule
cryptoNum = RustModule {
predicate = \ _ _ -> True,
outputName = "cryptonum",
isUnsigned = True,

View File

@@ -4,20 +4,20 @@ module Division(divisionOps)
import Data.Map.Strict(Map)
import qualified Data.Map.Strict as Map
import File
import Gen(toLit)
import Generators
import Language.Rust.Data.Ident
import Language.Rust.Data.Position
import Language.Rust.Quote
import Language.Rust.Syntax
import RustModule
import System.Random(RandomGen)
numTestCases :: Int
numTestCases = 3000
divisionOps :: File
divisionOps = File {
divisionOps :: RustModule
divisionOps = RustModule {
predicate = \ _ _ -> True,
outputName = "divmod",
isUnsigned = True,

View File

@@ -1,136 +0,0 @@
{-# LANGUAGE QuasiQuotes #-}
{-# LANGUAGE RankNTypes #-}
module File(
File(..),
Task(..),
generateTasks,
testFile
)
where
import Control.Monad(forM_)
import Data.Char(toUpper)
import Data.List(isPrefixOf)
import Data.Map.Strict(Map)
import qualified Data.Map.Strict as Map
import Language.Rust.Data.Ident(mkIdent)
import Language.Rust.Data.Position(Span)
import Language.Rust.Pretty(writeSourceFile)
import Language.Rust.Quote(item,sourceFile)
import Language.Rust.Syntax(SourceFile)
import System.FilePath(dropExtension,splitFileName,takeFileName,(</>))
import System.IO(Handle,hPutStrLn)
import System.Random(RandomGen(..))
data File = File {
predicate :: Word -> [Word] -> Bool,
outputName :: FilePath,
isUnsigned :: Bool,
generator :: Word -> [Word] -> SourceFile Span,
testCase :: forall g. RandomGen g => Maybe (Word -> g -> [Map String String])
}
data Task = Task {
outputFile :: FilePath,
writer :: Handle -> IO ()
}
testFile :: Bool -> Word -> FilePath
testFile True size = "U" ++ show5 size ++ ".test"
testFile False size = "I" ++ show5 size ++ ".test"
show5 :: Word -> String
show5 = go . show
where
go x | length x < 5 = go ('0' : x)
| otherwise = x
generateTasks :: RandomGen g => g -> [File] -> [Word] -> [Task]
generateTasks rng files sizes = basicTasks ++ moduleTasks
where
basicTasks = go rng files sizes
moduleTasks = generateModules basicTasks
--
go :: RandomGen g => g -> [File] -> [Word] -> [Task]
go _ [] _ = []
go g (_:rest) [] = go g rest sizes
go g files'@(file:_) (size:rest)
| not (predicate file size sizes) = go g files' rest
| otherwise =
let (myg, theirg) = split g
tasks = go theirg files' rest
(signedBit, prefix) | isUnsigned file = ("unsigned", "u")
| otherwise = ("signed", "i")
mainTask = Task {
outputFile = "src" </> signedBit </> (prefix ++ show size) </>
outputName file ++ ".rs",
writer = \ hndl -> writeSourceFile hndl (generator file size sizes)
}
in case testCase file of
Nothing ->
mainTask : tasks
Just caseGenerator ->
let testTask = Task {
outputFile = "testdata" </> outputName file </> testFile (isUnsigned file) size,
writer = \ hndl -> writeTestCase hndl (caseGenerator size myg)
}
in testTask : mainTask : tasks
generateModules :: [Task] -> [Task]
generateModules tasks = Map.foldrWithKey maddModule [] fileMap ++ [signedTask, unsignedTask]
where
maddModule path mods acc
| ("src/unsigned" `isPrefixOf` path) || ("src/signed" `isPrefixOf` path) =
let (basePath, lowerName) = splitFileName (init path)
upperName = map toUpper lowerName
task = Task {
outputFile = basePath </> lowerName ++ ".rs",
writer = \ hndl ->
do forM_ mods $ \ modl ->
hPutStrLn hndl ("mod " ++ modl ++ ";")
hPutStrLn hndl ("pub use base::" ++ upperName ++ ";")
}
in task : acc
| otherwise =
acc
fileMap = foldr buildBaseMap Map.empty tasks
buildBaseMap task acc =
let (dir, fileext) = splitFileName (outputFile task)
file = dropExtension fileext
in Map.insertWith (++) dir [file] acc
--
signedTask = moduleTask "signed"
unsignedTask = moduleTask "unsigned"
moduleTask kind =
let mods = Map.foldrWithKey (topModule kind) [] fileMap
pubuses = Map.foldrWithKey (pubUse kind) [] fileMap
in Task {
outputFile = "src" </> (kind ++ ".rs"),
writer = \ hndl ->
writeSourceFile hndl [sourceFile|
$@{mods}
$@{pubuses}
|]
}
topModule kind path _ acc
| ("src/" ++ kind) `isPrefixOf` path =
let lowerName = takeFileName (init path)
modl = mkIdent lowerName
in [item| mod $$modl; |] : acc
| otherwise =
acc
pubUse kind path _ acc
| ("src/" ++ kind) `isPrefixOf` path =
let lowerName = takeFileName (init path)
tname = mkIdent (map toUpper lowerName)
modl = mkIdent lowerName
in [item| pub use $$modl::$$tname; |] : acc
| otherwise =
acc
writeTestCase :: Handle -> [Map String String] -> IO ()
writeTestCase hndl tests =
forM_ tests $ \ test ->
forM_ (Map.toList test) $ \ (key, value) ->
hPutStrLn hndl (key ++ ": " ++ value)

View File

@@ -8,20 +8,20 @@ module ModInv(
import Control.Exception(assert)
import Data.Map.Strict(Map)
import qualified Data.Map.Strict as Map
import File
import Generators
import GHC.Integer.GMP.Internals(recipModInteger)
import Language.Rust.Data.Ident
import Language.Rust.Data.Position
import Language.Rust.Quote
import Language.Rust.Syntax
import RustModule
import System.Random(RandomGen)
numTestCases :: Int
numTestCases = 100
generateModInvOps :: File
generateModInvOps = File {
generateModInvOps :: RustModule
generateModInvOps = RustModule {
predicate = \ me others -> (me + 64) `elem` others,
outputName = "modinv",
isUnsigned = True,

View File

@@ -4,20 +4,20 @@ module ModOps(modulusOps)
import Data.Map.Strict(Map)
import qualified Data.Map.Strict as Map
import File
import Generators
import GHC.Integer.GMP.Internals(powModInteger)
import Language.Rust.Data.Ident
import Language.Rust.Data.Position
import Language.Rust.Quote
import Language.Rust.Syntax
import RustModule
import System.Random(RandomGen)
numTestCases :: Int
numTestCases = 1000
modulusOps :: File
modulusOps = File {
modulusOps :: RustModule
modulusOps = RustModule {
predicate = \ me others -> (me * 2) `elem` others,
outputName = "modops",
isUnsigned = True,

View File

@@ -9,7 +9,6 @@ import Data.Bits((.&.))
import Data.List(union)
import Data.Map.Strict(Map)
import qualified Data.Map.Strict as Map
import File
import Gen(toLit)
import Generators
import Karatsuba
@@ -17,13 +16,14 @@ import Language.Rust.Data.Ident
import Language.Rust.Data.Position
import Language.Rust.Quote
import Language.Rust.Syntax
import RustModule
import System.Random(RandomGen)
numTestCases :: Int
numTestCases = 3000
safeMultiplyOps :: File
safeMultiplyOps = File {
safeMultiplyOps :: RustModule
safeMultiplyOps = RustModule {
predicate = \ me others -> (me * 2) `elem` others,
outputName = "safe_mul",
isUnsigned = True,
@@ -31,8 +31,8 @@ safeMultiplyOps = File {
testCase = Just generateSafeTests
}
unsafeMultiplyOps :: File
unsafeMultiplyOps = File {
unsafeMultiplyOps :: RustModule
unsafeMultiplyOps = RustModule {
predicate = \ _ _ -> True,
outputName = "unsafe_mul",
isUnsigned = True,

View File

@@ -0,0 +1,191 @@
{-# LANGUAGE QuasiQuotes #-}
{-# LANGUAGE RankNTypes #-}
module RustModule(
RustModule(..),
Task(..),
generateTasks,
testFile
)
where
import Control.Monad(forM_)
import Data.Char(toUpper)
import Data.List(isPrefixOf, partition)
import Data.Map.Strict(Map)
import qualified Data.Map.Strict as Map
import Data.Maybe(mapMaybe)
import Language.Rust.Data.Ident(mkIdent)
import Language.Rust.Data.Position(Span, spanOf)
import Language.Rust.Pretty(writeSourceFile)
import Language.Rust.Quote(item, sourceFile)
import Language.Rust.Syntax(Item(..), SourceFile(..), Visibility(..))
import System.IO(Handle,hPutStrLn)
import System.Random(RandomGen(..))
data RustModule = RustModule {
predicate :: Word -> [Word] -> Bool,
outputName :: String,
isUnsigned :: Bool,
generator :: Word -> [Word] -> SourceFile Span,
testCase :: forall g. RandomGen g => Maybe (Word -> g -> [Map String String])
}
data Task = Task {
outputFile :: FilePath,
writer :: Handle -> IO ()
}
testFile :: Bool -> Word -> FilePath
testFile True size = "U" ++ show5 size ++ ".test"
testFile False size = "I" ++ show5 size ++ ".test"
show5 :: Word -> String
show5 = go . show
where
go x | length x < 5 = go ('0' : x)
| otherwise = x
generateTasks :: RandomGen g => g -> [RustModule] -> [Word] -> [Task]
generateTasks rng modules sizes = allTheFiles
where
allTheFiles = implementationsAndTests ++
[lump "src/signed", lump "src/unsigned"]
implementationsAndTests = concatMap generateModules sizes
--
lump prefix =
let allFiles = map outputFile implementationsAndTests
files = filter (prefix `isPrefixOf`) allFiles
moduleFiles = map (drop (length prefix + 1)) files
moduleNames = map (takeWhile (/= '.')) moduleFiles
moduleIdents = map mkIdent moduleNames
types = map (mkIdent . map toUpper) moduleNames
mods = map (\ name -> [item| mod $$name; |]) moduleIdents
uses = zipWith (\ mname tname -> [item| pub use $$mname::$$tname; |])
moduleIdents types
file = [sourceFile| $@{mods} $@{uses} |]
in Task (prefix ++ ".rs") (\hndl -> writeSourceFile hndl file)
--
generateModules size =
let modules' = filter (\m -> predicate m size sizes) modules
(umodules, smodules) = partition isUnsigned modules'
unsignedTasks = generateImplementations "U" size umodules
signedTasks = generateImplementations "I" size smodules
in unsignedTasks ++ signedTasks ++ mapMaybe (generateTests size rng) modules'
--
generateImplementations startsWith size modules'
| null modules' = []
| otherwise =
let name = mkIdent (startsWith ++ show size)
baseInclude = [item| pub use self::base::$$name; |]
moduleSources = map (generateSubmodule size sizes) modules'
moduleFile | startsWith == "I" = "src/signed/i" ++ show size ++ ".rs"
| otherwise = "src/unsigned/u" ++ show size ++ ".rs"
allSource = SourceFile Nothing [] (baseInclude : moduleSources)
in [Task moduleFile (\ hndl -> writeSourceFile hndl allSource)]
generateSubmodule :: Word -> [Word] -> RustModule -> Item Span
generateSubmodule size allSizes m =
let SourceFile _ attrs internals = generator m size allSizes
modName = mkIdent (outputName m)
modSpan = spanOf internals
in Mod attrs CrateV modName (Just internals) modSpan
generateTests :: RandomGen g =>
Word -> g ->
RustModule ->
Maybe Task
generateTests size rng m = fmap builder (testCase m)
where
builder testGeneration =
let outFile = "testdata/" ++ outputName m ++ "/" ++ testFile (isUnsigned m) size
testGenAction hndl = writeTestCase hndl (testGeneration size (snd (split rng)))
in Task outFile testGenAction
-- basicTasks ++ moduleTasks
-- where
-- basicTasks = go rng files sizes
-- moduleTasks = generateModules basicTasks
-- --
-- go :: RandomGen g => g -> [RustModule] -> [Word] -> [Task]
-- go _ [] _ = []
-- go g (_:rest) [] = go g rest sizes
-- go g files'@(file:_) (size:rest)
-- | not (predicate file size sizes) = go g files' rest
-- | otherwise =
-- let (myg, theirg) = split g
-- tasks = go theirg files' rest
-- (signedBit, prefix) | isUnsigned file = ("unsigned", "u")
-- | otherwise = ("signed", "i")
-- mainTask = Task {
-- outputFile = "src" </> signedBit </> (prefix ++ show size) </>
-- outputName file ++ ".rs",
-- writer = \ hndl -> writeSourceFile hndl (generator file size sizes)
-- }
-- in case testCase file of
-- Nothing ->
-- mainTask : tasks
-- Just caseGenerator ->
-- let testTask = Task {
-- outputFile = "testdata" </> outputName file </> testFile (isUnsigned file) size,
-- writer = \ hndl -> writeTestCase hndl (caseGenerator size myg)
-- }
-- in testTask : mainTask : tasks
--
--generateModules :: [Task] -> [Task]
--generateModules tasks = Map.foldrWithKey maddModule [] fileMap ++ [signedTask, unsignedTask]
-- where
-- maddModule path mods acc
-- | ("src/unsigned" `isPrefixOf` path) || ("src/signed" `isPrefixOf` path) =
-- let (basePath, lowerName) = splitFileName (init path)
-- upperName = map toUpper lowerName
-- task = Task {
-- outputFile = basePath </> lowerName ++ ".rs",
-- writer = \ hndl ->
-- do forM_ mods $ \ modl ->
-- hPutStrLn hndl ("mod " ++ modl ++ ";")
-- hPutStrLn hndl ("pub use base::" ++ upperName ++ ";")
-- }
-- in task : acc
-- | otherwise =
-- acc
-- fileMap = foldr buildBaseMap Map.empty tasks
-- buildBaseMap task acc =
-- let (dir, fileext) = splitFileName (outputFile task)
-- file = dropExtension fileext
-- in Map.insertWith (++) dir [file] acc
-- --
-- signedTask = moduleTask "signed"
-- unsignedTask = moduleTask "unsigned"
-- moduleTask kind =
-- let mods = Map.foldrWithKey (topModule kind) [] fileMap
-- pubuses = Map.foldrWithKey (pubUse kind) [] fileMap
-- in Task {
-- outputFile = "src" </> (kind ++ ".rs"),
-- writer = \ hndl ->
-- writeSourceFile hndl [sourceFile|
-- $@{mods}
-- $@{pubuses}
-- |]
-- }
-- topModule kind path _ acc
-- | ("src/" ++ kind) `isPrefixOf` path =
-- let lowerName = takeFileName (init path)
-- modl = mkIdent lowerName
-- in [item| mod $$modl; |] : acc
-- | otherwise =
-- acc
-- pubUse kind path _ acc
-- | ("src/" ++ kind) `isPrefixOf` path =
-- let lowerName = takeFileName (init path)
-- tname = mkIdent (map toUpper lowerName)
-- modl = mkIdent lowerName
-- in [item| pub use $$modl::$$tname; |] : acc
-- | otherwise =
-- acc
--
--
writeTestCase :: Handle -> [Map String String] -> IO ()
writeTestCase hndl tests =
forM_ tests $ \ test ->
forM_ (Map.toList test) $ \ (key, value) ->
hPutStrLn hndl (key ++ ": " ++ value)

View File

@@ -8,20 +8,20 @@ module Scale(
import Data.Bits((.&.))
import Data.Map.Strict(Map)
import qualified Data.Map.Strict as Map
import File
import Gen(toLit)
import Generators
import Language.Rust.Data.Ident
import Language.Rust.Data.Position
import Language.Rust.Quote
import Language.Rust.Syntax
import RustModule
import System.Random(RandomGen)
numTestCases :: Int
numTestCases = 3000
safeScaleOps :: File
safeScaleOps = File {
safeScaleOps :: RustModule
safeScaleOps = RustModule {
predicate = \ me others -> (me + 64) `elem` others,
outputName = "safe_scale",
isUnsigned = True,
@@ -29,8 +29,8 @@ safeScaleOps = File {
testCase = Just generateSafeTests
}
unsafeScaleOps :: File
unsafeScaleOps = File {
unsafeScaleOps :: RustModule
unsafeScaleOps = RustModule {
predicate = \ _ _ -> True,
outputName = "unsafe_scale",
isUnsigned = True,

View File

@@ -5,20 +5,20 @@ module Shift(shiftOps, signedShiftOps)
import Data.Bits(shiftL,shiftR)
import Data.Map.Strict(Map)
import qualified Data.Map.Strict as Map
import File
import Gen(toLit)
import Generators
import Language.Rust.Data.Ident
import Language.Rust.Data.Position
import Language.Rust.Quote
import Language.Rust.Syntax
import RustModule
import System.Random(RandomGen)
numTestCases :: Int
numTestCases = 3000
shiftOps :: File
shiftOps = File {
shiftOps :: RustModule
shiftOps = RustModule {
predicate = \ _ _ -> True,
outputName = "shift",
isUnsigned = True,
@@ -26,8 +26,8 @@ shiftOps = File {
testCase = Just generateTests
}
signedShiftOps :: File
signedShiftOps = File {
signedShiftOps :: RustModule
signedShiftOps = RustModule {
predicate = \ _ _ -> True,
outputName = "sshift",
isUnsigned = False,

View File

@@ -2,15 +2,14 @@
module Signed(signedBaseOps)
where
import File
import Language.Rust.Data.Ident
import Language.Rust.Data.Position
import Language.Rust.Quote
import Language.Rust.Syntax
import RustModule
signedBaseOps :: File
signedBaseOps = File {
signedBaseOps :: RustModule
signedBaseOps = RustModule {
predicate = const (const True),
outputName = "base",
isUnsigned = False,

View File

@@ -10,20 +10,20 @@ module Subtract(
import Data.Bits((.&.))
import Data.Map.Strict(Map)
import qualified Data.Map.Strict as Map
import File
import Gen(toLit)
import Generators
import Language.Rust.Data.Ident
import Language.Rust.Data.Position
import Language.Rust.Quote
import Language.Rust.Syntax
import RustModule
import System.Random(RandomGen)
numTestCases :: Int
numTestCases = 3000
safeSubtractOps :: File
safeSubtractOps = File {
safeSubtractOps :: RustModule
safeSubtractOps = RustModule {
predicate = \ me others -> (me + 64) `elem` others,
outputName = "safe_sub",
isUnsigned = True,
@@ -31,8 +31,8 @@ safeSubtractOps = File {
testCase = Just generateSafeTests
}
safeSignedSubtractOps :: File
safeSignedSubtractOps = File {
safeSignedSubtractOps :: RustModule
safeSignedSubtractOps = RustModule {
predicate = \ me others -> (me + 64) `elem` others,
outputName = "safe_ssub",
isUnsigned = False,
@@ -40,8 +40,8 @@ safeSignedSubtractOps = File {
testCase = Just generateSafeSignedTests
}
unsafeSubtractOps :: File
unsafeSubtractOps = File {
unsafeSubtractOps :: RustModule
unsafeSubtractOps = RustModule {
predicate = \ _ _ -> True,
outputName = "unsafe_sub",
isUnsigned = True,
@@ -49,8 +49,8 @@ unsafeSubtractOps = File {
testCase = Just generateUnsafeTests
}
unsafeSignedSubtractOps :: File
unsafeSignedSubtractOps = File {
unsafeSignedSubtractOps :: RustModule
unsafeSignedSubtractOps = RustModule {
predicate = \ _ _ -> True,
outputName = "unsafe_ssub",
isUnsigned = False,