diff --git a/Main.hs b/Main.hs index 0816012..350dab4 100644 --- a/Main.hs +++ b/Main.hs @@ -43,6 +43,7 @@ import Errors import FlowGraph import GenerateC import GenerateCPPCSP +import LexOccam import Metadata import ParseOccam import ParseRain @@ -66,7 +67,7 @@ optionsNoWarnings = , Option ['f'] ["compiler-flags"] (ReqArg optCompilerFlags "FLAGS") "flags for C/C++ compiler" , Option [] ["run-indent"] (NoArg $ optRunIndent) "run indent on source before compilation (will full mode)" , Option [] ["frontend"] (ReqArg optFrontend "FRONTEND") "language frontend (options: occam, rain)" - , Option [] ["mode"] (ReqArg optMode "MODE") "select mode (options: flowgraph, lex, parse, compile, post-c, full)" + , Option [] ["mode"] (ReqArg optMode "MODE") "select mode (options: flowgraph, lex, html, parse, compile, post-c, full)" , Option ['o'] ["output"] (ReqArg optOutput "FILE") "output file (default \"-\")" , Option [] ["sanity-check"] (ReqArg optSanityCheck "SETTING") "internal sanity check (options: on, off)" , Option [] ["occam2-mobility"] (ReqArg optClassicOccamMobility "SETTING") "occam2 implicit mobility (EXPERIMENTAL) (options: on, off)" @@ -91,6 +92,7 @@ optMode s ps "parse" -> return ModeParse "post-c" -> return ModePostC "lex" -> return ModeLex + "html" -> return ModeHTML _ -> dieIO (Nothing, "Unknown mode: " ++ s) return $ ps { csMode = mode } @@ -309,6 +311,41 @@ useOutputOptions func func f liftIO $ hClose f +showTokens :: Bool -> [Token] -> String +showTokens html ts = evalState (mapM showToken ts >>* spaceOut) 0 + where + spaceOut = foldl join "" + join prev (Right str) = prev ++ " " ++ str + join prev (Left spacing) + | spacing >= 0 = prev ++ concat (replicate spacing space) + | spacing < 0 = foldl (.) id (replicate (length space * negate spacing) init) $ prev + + showToken (Token _ tt) = showTokenType tt + + showTokenType :: TokenType -> State Int (Either Int String) + showTokenType (TokReserved s) = ret $ h s + showTokenType (TokIdentifier s) = ret s + showTokenType (TokStringCont s) = ret s + showTokenType (TokStringLiteral s) = ret s + showTokenType (TokCharLiteral s) = ret s + showTokenType (TokIntLiteral s) = ret s + showTokenType (TokHexLiteral s) = ret s + showTokenType (TokRealLiteral s) = ret s + showTokenType (TokPreprocessor s) = ret $ h s + showTokenType (IncludeFile s) = ret $ h "#INCLUDE \"" ++ s ++ "\"" + showTokenType (Pragma s) = ret $ h "#PRAGMA " ++ s + showTokenType (Indent) = modify (+2) >> return (Left 2) + showTokenType (Outdent) = modify (subtract 2) >> return (Left (-2)) + showTokenType (EndOfLine) + = do indentation <- get + ret $ newline ++ concat (replicate indentation space) + ret :: String -> State Int (Either Int String) + ret = return . Right + + (space, newline, h) = if html + then (" ", "
\n", \s -> "" ++ s ++ "") + else (" ", "\n", id) + -- | Compile a file. -- This is written in the PassM monad -- as are most of the things it calls -- -- because then it's very easy to pass the state around. @@ -324,6 +361,7 @@ compile mode fn outHandle case mode of -- In lex mode, don't parse, because it will probably fail anyway: ModeLex -> return (A.Only emptyMeta (), lexed) + ModeHTML -> return (A.Only emptyMeta (), lexed) _ -> do parsed <- parseOccamProgram lexed return (parsed, lexed) FrontendRain -> do parsed <- liftIO (readFile fn) >>= parseRainProgram fn @@ -333,6 +371,7 @@ compile mode fn outHandle case mode of ModeLex -> liftIO $ hPutStr outHandle $ pshow lexed + ModeHTML -> liftIO $ hPutStr outHandle $ showTokens True lexed ModeParse -> liftIO $ hPutStr outHandle $ pshow ast1 ModeFlowGraph -> do procs <- findAllProcesses diff --git a/data/CompState.hs b/data/CompState.hs index 7764ddd..f46cee7 100644 --- a/data/CompState.hs +++ b/data/CompState.hs @@ -38,7 +38,7 @@ import UnifyType import Utils -- | Modes that Tock can run in. -data CompMode = ModeFlowGraph | ModeLex | ModeParse | ModeCompile | ModePostC | ModeFull +data CompMode = ModeFlowGraph | ModeLex | ModeHTML | ModeParse | ModeCompile | ModePostC | ModeFull deriving (Show, Data, Typeable, Eq) -- | Backends that Tock can use.