packages feed

language-ocaml-0.1.31: lib/Language/OCaml/Parser/Expr.hs

module Language.OCaml.Parser.Expr
  ( exprP
  ) where

import Text.Megaparsec                              hiding (token)

import Language.OCaml.Definitions.Parsing.ParseTree
import Language.OCaml.Parser.Common
import Language.OCaml.Parser.FunDef
import Language.OCaml.Parser.LabeledSimplePattern
import Language.OCaml.Parser.LetBindings
import Language.OCaml.Parser.MatchCases
import Language.OCaml.Parser.OptBar
import Language.OCaml.Parser.Pattern
import Language.OCaml.Parser.SimpleLabeledExprList
import Language.OCaml.Parser.SimpleExpr
import Language.OCaml.Parser.Tokens
import Language.OCaml.Parser.Utils.Combinators
import Language.OCaml.Parser.Utils.Types
import Language.OCaml.PrettyPrinter                 ()

exprP :: Parser Structure -> Parser Expression -> Parser Expression
exprP structureP seqExprP = choice
  [ try $ parser <* notFollowedBy commaT
  , mkexp . PexpTuple . reverse <$>
    chainl1' parser (commaT *> (return $ flip (:))) (: [])
  ]
  where
    parser = leftRecursive
      [ try $ do
        e <- simpleExprP'
        l <- simpleLabeledExprListP'
        return $ mkexp $ PexpApply e (reverse l)
      , do
        b <- try $ do
          b <- letBindingsP structureP seqExprP
          inT
          return b
        e <- seqExprP
        return $ exprOfLetBindings b e
      -- FUNCTION
      , do
        try $ functionT
        -- TODO: extAttributes
        optBarP
        l <- matchCasesP'
        return $ mkexpAttrs (PexpFunction $ reverse l) (Nothing, []) -- FIXME
      -- FUN
      , do
        try $ funT
        -- TODO: extAttributes
        (l, o, p) <- labeledSimplePatternP patternP
        d <- funDefP seqExprP
        return $ mkexpAttrs (PexpFun l o p d) (Nothing, []) -- FIXME
      -- MATCH
      , do
        try $ matchT
        -- TODO: extAttributes
        e <- seqExprP
        withT
        optBarP
        l <- matchCasesP'
        return $ mkexpAttrs (PexpMatch e $ reverse l) (Nothing, []) -- FIXME
      -- IF ... THEN ... ELSE ...
      , do
        try ifT
        -- TODO: extAttributes
        c <- seqExprP
        thenT
        t <- exprP'
        e <- choice
          [ do
            try elseT
            Just <$> exprP'
          , return Nothing
          ]
        return $ mkexpAttrs (PexpIfThenElse c t e) (Nothing, []) -- FIXME
      , simpleExprP'
      ]
      -- FIXME: deal with associativity?
      [ infixP equalT   "="
      , infixP plusT    "+"
      , infixP minusT   "-"
      , infixP starT    "*"
      , infixP caretT   "^"
      , infixP greaterT ">"
      , infixP atT      "@"
      ]

    infixP :: Parser () -> String -> Parser (Expression -> Expression)
    infixP token symbol = try $ do
      token
      e2 <- exprP'
      return $ \ e1 -> mkinfix e1 symbol e2

    exprP'                     = exprP                     structureP seqExprP
    simpleExprP'              = simpleExprP                          seqExprP exprP'
    simpleLabeledExprListP' = simpleLabeledExprListP             seqExprP exprP'
    matchCasesP'              = matchCasesP                          seqExprP