Support a more complete (and simple) requirements gathering mechanism,
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.
This commit is contained in:
66
generation/src/File.hs
Normal file
66
generation/src/File.hs
Normal file
@@ -0,0 +1,66 @@
|
||||
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
|
||||
Reference in New Issue
Block a user