{-# LANGUAGE OverloadedStrings #-} module Language.SimpleShell.Parser.Function ( functionP ) where import Language.SimpleShell.AST.Expr (Expr) import Language.SimpleShell.AST.Function (Function(..)) import Language.SimpleShell.AST.Name (VarName) import Language.SimpleShell.AST.SimpleType (FunSig, Typed) import Language.SimpleShell.Parser (Parser, symbol, declareVars) import Language.SimpleShell.Parser.Expr (strongTermP) import Language.SimpleShell.Parser.Name (funNameP, varNameP, keyword) import Language.SimpleShell.Parser.SimpleType (simpleTypeP, forceType) import Control.Applicative ((<|>)) import Text.Megaparsec (sepBy) functionP :: Parser (FunSig, Function) functionP = do keyword "function" t' <- simpleTypeP fname <- funNameP params <- symbol "(" *> paramP `sepBy` symbol "," <* symbol ")" let (ts, vars) = unzip params body <- forceType t' (bodyP params) <|> fail "Function return type mismatch." return ((t', ts), Function fname vars body) paramP :: Parser (Typed VarName) paramP = (,) <$> simpleTypeP <*> varNameP bodyP :: [Typed VarName] -> Parser (Typed Expr) bodyP params = declareVars params strongTermP