module Parse.Declaration where
import Control.Applicative ((<$>))
import Text.Parsec ((<|>), (<?>), choice, digit, optionMaybe, string, try)
import qualified AST.Declaration as D
import qualified Parse.Expression as Expr
import Parse.Helpers
import qualified Parse.Type as Type
declaration :: IParser D.SourceDecl
declaration =
typeDecl <|> infixDecl <|> port <|> definition
definition :: IParser D.SourceDecl
definition = D.Definition <$> Expr.def
typeDecl :: IParser D.SourceDecl
typeDecl =
do reserved "type" <?> "type declaration"
forcedWS
isAlias <- optionMaybe (string "alias" >> forcedWS)
name <- capVar
args <- spacePrefix lowVar
padded equals
case isAlias of
Just _ ->
do tipe <- Type.expr <?> "a type"
return (D.TypeAlias name args tipe)
Nothing ->
do tcs <- pipeSep1 Type.constructor <?> "a constructor for a union type"
return $ D.Datatype name args tcs
infixDecl :: IParser D.SourceDecl
infixDecl = do
assoc <- choice [ reserved "infixl" >> return D.L
, reserved "infix" >> return D.N
, reserved "infixr" >> return D.R ]
forcedWS
n <- digit
forcedWS
D.Fixity assoc (read [n]) <$> anyOp
port :: IParser D.SourceDecl
port =
do try (reserved "port")
whitespace
name <- lowVar
whitespace
let port' op ctor expr = do { try op ; whitespace ; ctor name <$> expr }
D.Port <$> choice [ port' hasType D.PPAnnotation Type.expr
, port' equals D.PPDef Expr.expr ]