Skip to content

Commit

Permalink
Sockeye: Improve import handling
Browse files Browse the repository at this point in the history
Signed-off-by: Daniel Schwyn <[email protected]>
  • Loading branch information
dasch8 committed Jul 24, 2017
1 parent 7d46621 commit f7c561e
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 35 deletions.
6 changes: 4 additions & 2 deletions hake/RuleDefs.hs
Original file line number Diff line number Diff line change
Expand Up @@ -782,8 +782,9 @@ skateGenSchemas opts schema =
-- Build SKB facts from Sockeye file
--
sockeyeProgLoc = In InstallTree "tools" "/bin/sockeye"
sockeyeSocFileLoc d = In SrcTree "src" ("/socs" </> (d ++ ".soc"))
sockeyeFactFilePath d = "/sockeyefacts" </> (d ++ ".pl")
sockeyeSocDir = In SrcTree "src" "/socs"
sockeyeSocFileLoc d = In SrcTree "src" ("/socs" </> d <.> "soc")
sockeyeFactFilePath d = "/sockeyefacts" </> d <.> "pl"
sockeyeFactFileLoc d = In BuildTree "" $ sockeyeFactFilePath d

sockeye :: String -> HRule
Expand All @@ -794,6 +795,7 @@ sockeye net =
in Rules
[ Rule
[ sockeyeProgLoc
, Str "-i", sockeyeSocDir
, Str "-o", Out "" factFile
, Str "-d", Out "" depFile
, sockeyeSocFileLoc net
Expand Down
2 changes: 1 addition & 1 deletion socs/omap44xx/cortexA9-subsystem.soc
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
*
*/

import ../cortex/cortexA9
import cortex/cortexA9

module CortexA9-Subsystem {
input CPU_{[1..2]}/32
Expand Down
82 changes: 51 additions & 31 deletions tools/sockeye/Main.hs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import Data.List (intercalate)
import qualified Data.Map as Map

import System.Console.GetOpt
import System.Directory
import System.Exit
import System.Environment
import System.FilePath
Expand All @@ -38,37 +39,47 @@ import qualified SockeyeBackendProlog as Prolog
usageError :: ExitCode
usageError = ExitFailure 1

fileError :: ExitCode
fileError = ExitFailure 2

parseError :: ExitCode
parseError = ExitFailure 2
parseError = ExitFailure 3

checkError :: ExitCode
checkError = ExitFailure 3
checkError = ExitFailure 4

buildError :: ExitCode
buildError = ExitFailure 4
buildError = ExitFailure 5

{- Compilation targets -}
data Target = Prolog

{- Possible options for the Sockeye Compiler -}
data Options = Options { optInputFile :: FilePath
, optTarget :: Target
, optOutputFile :: FilePath
, optDepFile :: Maybe FilePath
}
data Options = Options
{ optInputFile :: FilePath
, optInclDirs :: [FilePath]
, optTarget :: Target
, optOutputFile :: FilePath
, optDepFile :: Maybe FilePath
}

{- Default options -}
defaultOptions :: Options
defaultOptions = Options { optInputFile = ""
, optTarget = Prolog
, optOutputFile = ""
, optDepFile = Nothing
}
defaultOptions = Options
{ optInputFile = ""
, optInclDirs = [""]
, optTarget = Prolog
, optOutputFile = ""
, optDepFile = Nothing
}

{- Set the input file name -}
optSetInputFileName :: FilePath -> Options -> Options
optSetInputFileName f o = o { optInputFile = f }

optAddInclDir :: FilePath -> Options -> Options
optAddInclDir f o = o { optInclDirs = optInclDirs o ++ [f] }

{- Set the target -}
optSetTarget :: Target -> Options -> Options
optSetTarget t o = o { optTarget = t }
Expand Down Expand Up @@ -99,6 +110,9 @@ options =
[ Option "P" ["Prolog"]
(NoArg (\opts -> return $ optSetTarget Prolog opts))
"Generate a prolog file that can be loaded into the SKB (default)."
, Option "i" ["include"]
(ReqArg (\f opts -> return $ optAddInclDir f opts) "DIR")
"Add a directory to the search path where Sockeye looks for imports."
, Option "o" ["output-file"]
(ReqArg (\f opts -> return $ optSetOutputFile f opts) "FILE")
"Output file in which to store the compilation result (required)."
Expand Down Expand Up @@ -137,11 +151,10 @@ compilerOpts argv = do
_ -> return opts

{- Parse Sockeye and resolve imports -}
parseSpec :: FilePath -> IO (ParseAST.SockeyeSpec, [FilePath])
parseSpec file = do
let
rootImport = ParseAST.Import file
specMap <- parseWithImports "" Map.empty rootImport
parseSpec :: [FilePath] -> FilePath -> IO (ParseAST.SockeyeSpec, [FilePath])
parseSpec inclDirs fileName = do
file <- resolveFile fileName
specMap <- parseWithImports Map.empty file
let
specs = Map.elems specMap
deps = Map.keys specMap
Expand All @@ -152,25 +165,32 @@ parseSpec file = do
, ParseAST.modules = modules
}
return (spec, deps)

where
parseWithImports pwd importMap (ParseAST.Import filePath) = do
let
dir = case pwd of
"" -> takeDirectory filePath
_ -> pwd </> takeDirectory filePath
fileName = takeFileName filePath
file = if '.' `elem` fileName
then dir </> fileName
else dir </> fileName <.> "soc"
parseWithImports importMap importPath = do
file <- resolveFile importPath
if file `Map.member` importMap
then return importMap
else do
ast <- parseFile file
let
specMap = Map.insert file ast importMap
imports = ParseAST.imports ast
foldM (parseWithImports dir) specMap imports
importFiles = map ParseAST.filePath imports
foldM parseWithImports specMap importFiles
resolveFile path = do
let
subDir = takeDirectory path
name = takeFileName path
dirs = map (</> subDir) inclDirs
file <- findFile dirs name
extFile <- findFile dirs (name <.> "soc")
case (file, extFile) of
(Just f, _) -> return f
(_, Just f) -> return f
_ -> do
hPutStrLn stderr $ "'" ++ path ++ "' not on import path"
exitWith fileError


{- Runs the parser on a single file -}
parseFile :: FilePath -> IO (ParseAST.SockeyeSpec)
Expand Down Expand Up @@ -221,10 +241,10 @@ main = do
opts <- compilerOpts args
let
inFile = optInputFile opts
inclDirs = optInclDirs opts
outFile = optOutputFile opts
depFile = optDepFile opts
target = optTarget opts
(parsedAst, deps) <- parseSpec inFile
(parsedAst, deps) <- parseSpec inclDirs inFile
case depFile of
Nothing -> return ()
Just f -> do
Expand Down
2 changes: 1 addition & 1 deletion tools/sockeye/SockeyeParser.hs
Original file line number Diff line number Diff line change
Expand Up @@ -356,7 +356,7 @@ keywords = ["import", "module",
identStart = letter
identLetter = alphaNum <|> char '_' <|> char '-'

importPath = many (identLetter <|> char '/' <|> char '.') <* whiteSpace
importPath = many (identLetter <|> char '/') <* whiteSpace
moduleName = identString <?> "module name"
parameterName = identString <?> "parameter name"
variableName = identString <?> "variable name"
Expand Down

0 comments on commit f7c561e

Please sign in to comment.