and add support for binary operations. This version of requirements generation simply generates every numeric size within a provided range, and then will reject trait implementations that rely on values outside this range. It should be a little more easy to reason about, and easier to make local changes as I (inevitably) need to modify rules.
66 lines
1.9 KiB
Haskell
66 lines
1.9 KiB
Haskell
module File(
|
|
File(..),
|
|
Task(..),
|
|
addModuleTasks,
|
|
makeTask
|
|
)
|
|
where
|
|
|
|
import Control.Monad(forM_)
|
|
import Data.Char(toUpper)
|
|
import qualified Data.Map.Strict as Map
|
|
import Gen(Gen,blank,out)
|
|
import System.FilePath(takeBaseName,takeDirectory,takeFileName,(</>))
|
|
|
|
data File = File {
|
|
predicate :: Word -> [Word] -> Bool,
|
|
outputName :: FilePath,
|
|
generator :: Word -> Gen ()
|
|
}
|
|
|
|
data Task = Task {
|
|
outputFile :: FilePath,
|
|
fileGenerator :: Gen ()
|
|
}
|
|
|
|
makeTask :: FilePath ->
|
|
Word -> [Word] ->
|
|
File ->
|
|
Maybe Task
|
|
makeTask base size allSizes file
|
|
| predicate file size allSizes =
|
|
Just Task {
|
|
outputFile = base </> ("u" ++ show size) </> outputName file <> ".rs",
|
|
fileGenerator = generator file size
|
|
}
|
|
| otherwise =
|
|
Nothing
|
|
|
|
addModuleTasks :: FilePath -> [Task] -> [Task]
|
|
addModuleTasks base baseTasks = unsignedTask : (baseTasks ++ moduleTasks)
|
|
where
|
|
moduleMap = foldr addModuleInfo Map.empty baseTasks
|
|
addModuleInfo task =
|
|
Map.insertWith (++) (takeDirectory (outputFile task))
|
|
[takeBaseName (outputFile task)]
|
|
moduleTasks = Map.foldrWithKey generateModuleTask [] moduleMap
|
|
generateModuleTask directory mods acc = acc ++ [Task {
|
|
outputFile = directory </> "mod.rs",
|
|
fileGenerator =
|
|
do forM_ mods $ \ modle -> out ("mod " ++ modle ++ ";")
|
|
blank
|
|
out ("pub use base::" ++ upcase (takeFileName directory) ++ ";")
|
|
}]
|
|
unsignedTask = Task {
|
|
outputFile = base </> "unsigned" </> "mod.rs",
|
|
fileGenerator =
|
|
do forM_ (Map.keys moduleMap) $ \ key ->
|
|
out ("mod " ++ takeFileName key ++ ";")
|
|
blank
|
|
forM_ (Map.keys moduleMap) $ \ key ->
|
|
out ("pub use " ++ takeFileName key ++ "::" ++
|
|
upcase (takeFileName key) ++ ";")
|
|
}
|
|
|
|
upcase :: String -> String
|
|
upcase = map toUpper |