ubcc/src/Ubc/Parse/Syntax/Function.hs

57 lines
1.8 KiB
Haskell

{-# LANGUAGE OverloadedStrings #-}
module Ubc.Parse.Syntax.Function
( Function(..)
, parse
, parsePrefixed
)
where
import Control.Monad ((<$!>))
import Text.Parsec (lookAhead, try, ParsecT)
import Ubc.Parse.Syntax.VariableType (VariableType)
import {-# SOURCE #-} Ubc.Parse.Syntax.Expression (Expression, expressionParser)
import Ubc.Parse.Syntax.Generic (Generic)
import qualified Ubc.Parse.Syntax.Language as UbcLanguage
import qualified Ubc.Parse.Syntax.VariableType as VariableType
import qualified Ubc.Parse.Syntax.Generic as Generic
import Ubc.Parse.Syntax (Token)
data Function = Function
{ returnType :: VariableType
, identifier :: Token
, generics :: [Generic]
, body :: Expression
, arguments :: [(VariableType, Token)]
}
deriving (Show)
parsePrefixed :: Monad m => VariableType -> Token -> ParsecT Token u m Function
parsePrefixed ftype fname = do
genericList <- UbcLanguage.angles $ UbcLanguage.commaSeparated1 Generic.parse
argumentList <- UbcLanguage.parens (UbcLanguage.commaSeparated argumentDefinition)
expressionBody <- expressionParser
return $ Function ftype fname genericList expressionBody argumentList
parse :: Monad m => ParsecT Token u m Function
parse = do
(resultType, name) <- try $ do
resultType <- UbcLanguage.typeName
name <- UbcLanguage.identifier
_ <- lookAhead $ UbcLanguage.symbol "("
return (VariableType.fromString resultType, name)
parsePrefixed resultType name
argumentDefinition :: Monad m => ParsecT Token u m (VariableType, Token)
argumentDefinition = do
argumentType <- VariableType.fromString <$!> UbcLanguage.typeName
argumentName <- UbcLanguage.identifier
return (argumentType, argumentName)