module Calculator.Parser.Cmd ( parseCmd , parseAssignCmd , parseAssign , parseFuncCmd , parseFunc ) where -------------------------------------------------------------------------------- import Calculator.Parser.Base (parseId) import Calculator.Parser.Expr (parseExpr) import Calculator.Prim.Cmd (Cmd (..)) import Calculator.Prim.Expr (Expr) -------------------------------------------------------------------------------- import Control.Applicative ((<*)) import Text.ParserCombinators.Parsec -------------------------------------------------------------------------------- -- cmd -> ':' cmd' parseCmd :: Parser Cmd parseCmd = char ':' >> parseCmd' -------------------------------------------------------------------------------- -- cmd' -> show | help | reset | assign | plot parseCmd' :: Parser Cmd parseCmd' = parseShow <|> parseHelp <|> parseReset <|> parseAssignCmd <|> parseFuncCmd <|> parsePlotCmd -------------------------------------------------------------------------------- -- help -> "?" | "help" parseHelp :: Parser Cmd parseHelp = (string "?" <|> string "help") >> spaces >> return Help -------------------------------------------------------------------------------- -- show -> "show" parseShow :: Parser Cmd parseShow = string "show" >> spaces >> return Display -------------------------------------------------------------------------------- -- reset -> "reset" parseReset :: Parser Cmd parseReset = string "reset" >> spaces >> return Reset -------------------------------------------------------------------------------- -- plot -> "plot" id parsePlotCmd :: Parser Cmd parsePlotCmd = do _ <- string "plot" _ <- spaces f <- parseId _ <- spaces r <- pairDoubles `sepBy1` spaces return $ Plot f r pairDoubles :: Parser (Expr, Expr) pairDoubles = do _ <- char '(' _ <- spaces l <- parseExpr _ <- spaces _ <- char ',' _ <- spaces u <- parseExpr _ <- spaces _ <- char ')' return (l, u) -------------------------------------------------------------------------------- -- assignCmd -> "var" id "=" expr parseAssignCmd :: Parser Cmd parseAssignCmd = string "var" >> space >> spaces >> parseAssign parseAssign :: Parser Cmd parseAssign = do str <- parseId _ <- spaces _ <- char '=' _ <- spaces ex <- parseExpr return $ Assign str ex -------------------------------------------------------------------------------- -- func -> "func" id (args) "=" expr parseFuncCmd :: Parser Cmd parseFuncCmd = string "func" >> space >> spaces >> parseFunc parseFunc :: Parser Cmd parseFunc = do ident <- try (parseId <* (spaces >> char '(' >> spaces)) args <- (parseId <* spaces) `sepBy` (char ',' <* spaces) <* char ')' _ <- spaces >> char '=' <* spaces expr <- parseExpr return $ Func ident args expr --------------------------------------------------------------------------------