Skip to content

Instantly share code, notes, and snippets.

@prakashk
Last active August 29, 2015 14:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save prakashk/3aeb22c4fee683d011fd to your computer and use it in GitHub Desktop.
Save prakashk/3aeb22c4fee683d011fd to your computer and use it in GitHub Desktop.
import System.Environment (getArgs)
import Text.Parsec
import Text.Parsec.Prim
import Text.Parsec.Language
import qualified Text.Parsec.Token as T
import Control.Applicative ((<$>), (*>))
type Parser = Parsec String ()
-- AST
data Program = Program [Statement]
deriving (Show)
data Statement = Print String
| Use FilePath
deriving (Show)
myLangDef = emptyDef {
T.reservedNames = [ "print", "use" ]
}
lexer = T.makeTokenParser myLangDef
reserved = T.reserved lexer
stringLiteral = T.stringLiteral lexer
parseString :: String -> Program
parseString input = case parse program "" input of
Left msg -> error (show msg)
Right p -> p
parseFile :: String -> IO Program
parseFile fname = parseString <$> readFile fname
-- parsers
program :: Parser Program
program = Program <$> many statement
statement :: Parser Statement
statement = printStr <|> useFile
printStr :: Parser Statement
printStr = Print <$> (reserved "print" *> stringLiteral)
useFile :: Parser Statement
useFile = Use <$> (reserved "use" *> stringLiteral)
-- read contents of "use"d files, parse and insert in the main AST
expandProgram :: Program -> IO Program
expandProgram (Program stmts) = Program <$> (includeUsedFiles stmts)
where includeUsedFiles :: [Statement] -> IO [Statement]
includeUsedFiles = fmap concat <$> mapM expandStatement
expandStatement :: Statement -> IO [Statement]
expandStatement stmt =
case stmt of
Use file -> getStatements <$> parseFile file >>= includeUsedFiles
_ -> return [stmt]
getStatements :: Program -> [Statement]
getStatements (Program stmts) = stmts
main = do
head <$> getArgs
>>= parseFile
>>= expandProgram
>>= print
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment