packages feed

calculator-0.2.2.0: src/Calculator/Parser/Cmd.hs

module Calculator.Parser.Cmd
    ( parseCmd
    , parseAssign
    , parseAssign'
    , parseFunc
    , parseFunc'
    ) where

--------------------------------------------------------------------------------

import           Calculator.Parser.Base        (parseId)
import           Calculator.Parser.Expr        (parseExpr)
import           Calculator.Prim.Cmd           (Cmd (..))

--------------------------------------------------------------------------------

import           Control.Applicative           ((<*))
import           Text.ParserCombinators.Parsec

--------------------------------------------------------------------------------
-- cmd -> ':' cmd'

parseCmd :: Parser Cmd
parseCmd = char ':' >> parseCmd'

--------------------------------------------------------------------------------
-- cmd' -> show | help | reset | assign

parseCmd' :: Parser Cmd
parseCmd' = parseShow
         <|> parseHelp
         <|> parseReset
         <|> parseAssign
         <|> parseFunc

--------------------------------------------------------------------------------
-- help -> "?" | "help"

parseHelp :: Parser Cmd
parseHelp = (string "?" <|> string "help") >> spaces >> return Help

--------------------------------------------------------------------------------
-- reset -> "reset"

parseShow :: Parser Cmd
parseShow = string "show" >> spaces >> return Display

--------------------------------------------------------------------------------
-- reset -> "reset"

parseReset :: Parser Cmd
parseReset = string "reset" >> spaces >> return Reset

--------------------------------------------------------------------------------
-- assign -> "var" id "=" expr

parseAssign :: Parser Cmd
parseAssign = 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

parseFunc :: Parser Cmd
parseFunc = 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

--------------------------------------------------------------------------------