module Ubc.Parse.Syntax.Statement ( Statement(..) , parse , blockExpression ) where import Ubc.Parse.Syntax.VariableType (VariableType) import {-# SOURCE #-} Ubc.Parse.Syntax.Expression (expressionParser, Expression (Block)) import Ubc.Parse.Syntax.TypeExpression (TypeExpression) import Text.Parsec (choice, ParsecT, try, many) import qualified Ubc.Parse.Syntax.Language as UbcLanguage import qualified Ubc.Parse.Syntax.VariableType as VariableType import qualified Ubc.Parse.Syntax.TypeExpression as TypeExpression import Control.Monad ((<$!>)) import Data.Functor ((<&>)) type VariableName = String type TypeName = String data Statement = VariableDefinition VariableType VariableName Expression | TypeDefinition TypeName TypeExpression | ExpressionStatement Expression deriving (Show) parse :: Monad m => ParsecT String u m Statement parse = choice [ variableDefinition , typeDefinition , ExpressionStatement <$!> expressionParser ] typeDefinition :: Monad m => ParsecT String u m Statement typeDefinition = do UbcLanguage.reserved "type" name <- UbcLanguage.identifier UbcLanguage.reservedOperator "=" TypeDefinition name <$> TypeExpression.parseTypeExpression variableDefinition :: Monad m => ParsecT String u m Statement variableDefinition = do (variableType, variableName) <- try $ do variableType <- UbcLanguage.typeName variableName <- UbcLanguage.identifier _ <- UbcLanguage.reservedOperator "=" return (VariableType.fromString variableType, variableName) VariableDefinition variableType variableName <$> expressionParser blockExpression :: Monad m => ParsecT String u m Expression blockExpression = UbcLanguage.braces (many parse) <&> Block