{-# 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)