diff --git a/CompState.hs b/CompState.hs index 9e44e1d..72e2f36 100644 --- a/CompState.hs +++ b/CompState.hs @@ -35,12 +35,17 @@ data CompMode = ModeParse | ModeCompile | ModePostC -- | Backends that Tock can use. data CompBackend = BackendC | BackendCPPCSP deriving (Show, Data, Typeable) + +-- | Frontends that Tock can use. +data CompFrontend = FrontendOccam21 | FrontendRain + deriving (Show, Data, Typeable) -- | State necessary for compilation. data CompState = CompState { -- Set by Main (from command-line options) csMode :: CompMode, csBackend :: CompBackend, + csFrontend :: CompFrontend, csVerboseLevel :: Int, csOutputFile :: String, @@ -76,6 +81,7 @@ emptyState :: CompState emptyState = CompState { csMode = ModeCompile, csBackend = BackendC, + csFrontend = FrontendOccam21, csVerboseLevel = 0, csOutputFile = "-", diff --git a/Main.hs b/Main.hs index e160c6f..ffc2cdf 100644 --- a/Main.hs +++ b/Main.hs @@ -35,6 +35,8 @@ import GenerateCPPCSP import Parse import Pass import PrettyShow +import RainParse +import RainPasses import SimplifyExprs import SimplifyProcs import SimplifyTypes @@ -54,6 +56,7 @@ options :: [OptDescr OptFunc] options = [ Option [] ["mode"] (ReqArg optMode "MODE") "select mode (options: parse, compile, post-c)" , Option [] ["backend"] (ReqArg optBackend "BACKEND") "code-generating backend (options: c, cppcsp)" + , Option [] ["frontend"] (ReqArg optFrontend "FRONTEND") "language frontend (options: occam21, rain)" , Option ['v'] ["verbose"] (NoArg $ optVerbose) "be more verbose (use multiple times for more detail)" , Option ['o'] ["output"] (ReqArg optOutput "FILE") "output file (default \"-\")" ] @@ -75,6 +78,14 @@ optBackend s ps _ -> dieIO $ "Unknown backend: " ++ s return $ ps { csBackend = backend } +optFrontend :: String -> OptFunc +optFrontend s ps + = do frontend <- case s of + "occam21" -> return FrontendOccam21 + "rain" -> return FrontendRain + _ -> dieIO $ "Unknown frontend: " ++ s + return $ ps { csFrontend = frontend } + optVerbose :: OptFunc optVerbose ps = return $ ps { csVerboseLevel = csVerboseLevel ps + 1 } @@ -136,7 +147,9 @@ compile fn debug "{{{ Parse" progress "Parse" - ast1 <- parseProgram fn + ast1 <- case csFrontend optsPS of + FrontendOccam21 -> parseProgram fn + FrontendRain -> parseRainProgram fn debugAST ast1 debug "}}}" @@ -147,7 +160,10 @@ compile fn ModeParse -> return $ show ast1 ModeCompile -> do progress "Passes:" - ast2 <- (runPasses passes) ast1 + ast2 <- case csFrontend optsPS of + FrontendOccam21 -> (runPasses passes) ast1 + --Run the rain passes, then all the normal occam passes too: + FrontendRain -> ((runPasses rainPasses) ast1) >>= (runPasses passes) debug "{{{ Generate code" let generator diff --git a/RainParse.hs b/RainParse.hs index 5715f0d..3477ded 100644 --- a/RainParse.hs +++ b/RainParse.hs @@ -269,4 +269,30 @@ statement } <|> do { m <- md ; sSemiColon ; return $ A.Skip m} "statement" ---TODO the "each" statements + +rainSourceFile :: RainParser (A.Process, CompState) +rainSourceFile + = do whiteSpace + --TODO change from stattement to declaration (once the latter is written): + p <- statement + s <- getState + return (p, s) + +-- | Parse a file with the given production. +-- This is copied from Parse.hs (because OccParser is about to be changed to not be the same as RainParser): +parseFile :: Monad m => String -> RainParser t -> CompState -> m t +parseFile file prod ps + = do let source = case Map.lookup file (csSourceFiles ps) of + Just s -> s + Nothing -> dieIO $ "Failed to preload file: " ++ show file + let ps' = ps { csLoadedFiles = file : csLoadedFiles ps } + case runParser prod ps' file source of + Left err -> dieIO $ "Parse error: " ++ show err + Right r -> return r + +parseRainProgram :: String -> PassM A.Process +parseRainProgram file + = do ps <- get + (p, ps') <- parseFile file rainSourceFile ps + put ps' + return p diff --git a/RainPasses.hs b/RainPasses.hs index 41d3242..da0c54f 100644 --- a/RainPasses.hs +++ b/RainPasses.hs @@ -26,10 +26,8 @@ import Types import CompState import Errors -rainPasses :: A.Process -> PassM A.Process -rainPasses = runPasses passes - where - passes = +rainPasses :: [(String,Pass)] +rainPasses = [ ("Uniquify variable declarations and resolve variable names",uniquifyAndResolveVars) ,("Record declared name types in dictionary",recordDeclNameTypes) ,("Record inferred name types in dictionary",recordInfNameTypes)