{-# LANGUAGE DeriveGeneric, PatternSynonyms, ViewPatterns #-} -- | The Ast module describes a generic, abstract language AST. -- | -- | Since it only describes the AST, but not many aspects of its semantics, Mulang is non-computable, but just a target -- | for code analysis. -- | -- | Mulang AST itself is the combination of other abstract, paradigmatic languages that express the structures of: -- | * imperative programing -- | * object-oriented programing -- | * functional programing -- | * logic programing -- | module Language.Mulang.Ast ( equationParams, Code, Equation(..), EquationBody(..), Expression(..), ComprehensionStatement(..), Pattern(..), Identifier, pattern SimpleEquation, pattern SimpleFunction, pattern SimpleProcedure, pattern SimpleMethod, pattern SimpleSend, pattern MuTrue, pattern MuFalse, pattern Subroutine, pattern Clause, pattern Call, pattern Params ) where import GHC.Generics import Language.Mulang.Identifier (Identifier) type Code = String -- | An equation. See @Function@ and @Procedure@ above data Equation = Equation [Pattern] EquationBody deriving (Eq, Show, Read, Generic) data EquationBody = UnguardedBody Expression | GuardedBody [(Expression, Expression)] deriving (Eq, Show, Read, Generic) -- | Expression is the root element of a Mulang program. -- | With the exception of Patterns, nearly everything is an Expression: variable declarations, literals, -- | control structures, even object oriented classes declarations. -- | -- | However, although all those elements can be used as subexpressions and have an dohave an associated value, -- | Mulang does not state WHICH is that value. data Expression = TypeAlias Identifier -- ^ Functional programming type alias. -- Only the type alias identifier is parsed | Record Identifier -- ^ Imperative / Functional programming struct declaration. -- Only the record name is parsed | TypeSignature Identifier [Identifier] Identifier -- ^ Generic type signature for a computation, -- composed by a name, parameter types and return type | EntryPoint Identifier Expression -- ^ Entry point with its body | Function Identifier [Equation] -- ^ Functional / Imperative programming function declaration. -- It is is composed by an identifier and one or more equations | Procedure Identifier [Equation] -- ^ Imperative programming procedure declaration. It is composed by a name and one or more equations | Method Identifier [Equation] | EqualMethod [Equation] | HashMethod [Equation] | Variable Identifier Expression | Assignment Identifier Expression | Attribute Identifier Expression -- ^ Object oriented programming attribute declaration, composed by an identifier and an initializer | Object Identifier Expression -- ^ Object oriented programming global, named object declaration, -- composed by a name and a body | Class Identifier (Maybe Identifier) Expression -- ^ Object oriented programming global, class declaration, -- composed by a name, an optional superclass, implemented interfaces and a body | Enumeration Identifier [Identifier] -- ^ Imperative named enumeration of values | Interface Identifier [Identifier] Expression -- ^ Object oriented programming global interface or contract declaration, -- composed by a name, superinterfaces and a body | Rule Identifier [Pattern] [Expression] -- ^ Logic programming declaration of a fact, composed by the rue name, rule arguments, and rule body | Fact Identifier [Pattern] -- ^ Logic programming declaration of a fact , composed by the fact name and fact arguments | Exist Identifier [Pattern] -- ^ Logic programming existential cuantification / consult | Not Expression -- ^ Logic programming negation | Findall Expression Expression Expression -- ^ Logic programming findall | Forall Expression Expression -- ^ Logic programming universal cuantification | Reference Identifier -- ^ Generic variable | Application Expression [Expression] -- ^ Generic, non-curried application of a function or procedure, composed by the applied element itself, and the application arguments | Send Expression Expression [Expression] -- ^ Object oriented programming message send, composed by the reciever, selector and arguments | New Identifier [Expression] -- ^ Object oriented instantiation, composed by the class reference and instantiation arguments | Implement Identifier -- ^ Object oriented instantiation, interface implementation | Include Identifier -- ^ Object oriented instantiation, mixin inclusion | Lambda [Pattern] Expression | If Expression Expression Expression | Return Expression | While Expression Expression -- ^ Imperative programming conditional repetition control structure, composed by a condition and a body | Repeat Expression Expression -- ^ Imperative programming fixed repetition control structure, composed by a repetition count expression, and a body | Match Expression [Equation] | Switch Expression [(Expression, Expression)] Expression | Try Expression [(Pattern, Expression)] Expression -- ^ Generic try expression, composed by a body, a list of exception-handling patterns and statments, and a finally expression | Raise Expression -- ^ Generic raise expression, like a throw or raise statament, composed by the raised expression | Print Expression -- ^ Generic print expression | Comprehension Expression [ComprehensionStatement] | Sequence [Expression] -- ^ Generic sequence of statements | Other | Equal | NotEqual | Self | MuNull -- ^ Generic value indicating an absent expression, such as when there is no finally in a try or default in a switch or js' undefined | MuNil -- ^ Generic nothing value literal - nil, null or unit | MuObject Expression -- ^ Object oriented unnamed object literal | MuNumber Double -- ^ Generic number literal | MuBool Bool -- ^ Generic boolean literal | MuString String -- ^ Generic string literal | MuSymbol String -- ^ Generic symbol/atom literal | MuTuple [Expression] | MuList [Expression] deriving (Eq, Show, Read, Generic) -- | Mulang Patterns are not expressions, but are aimed to match them. -- | They are modeled after Haskell, Prolog, Elixir, Scala and Erlang patterns data Pattern = VariablePattern String -- ^ variable pattern like @X@ | LiteralPattern String -- ^ literal constant pattern like @4@ | InfixApplicationPattern Pattern String Pattern -- ^ infix application pattern like @4:X@ | ApplicationPattern String [Pattern] -- ^ prefix application pattern like @f _@ | TuplePattern [Pattern] -- ^ tuple pattern like @(3, _)@ | ListPattern [Pattern] -- ^ list pattern like @[x, y, _]@ | FunctorPattern Identifier [Pattern] -- ^ prolog-like functor pattern, like @f(X, 6)@ | AsPattern Identifier Pattern | TypePattern Identifier -- ^ @\@@-pattern | WildcardPattern -- ^ wildcard pattern @_@ | UnionPattern [Pattern] | OtherPattern -- ^ Other unrecognized pattern deriving (Eq, Show, Read, Generic) data ComprehensionStatement = MuGenerator Pattern Expression | MuQualifier Expression | LetStmt Expression deriving (Eq, Show, Read, Generic) pattern SimpleEquation params body = Equation params (UnguardedBody body) pattern SimpleSend receptor selector args = Send receptor (Reference selector) args pattern SimpleFunction name params body = Function name [SimpleEquation params body] pattern SimpleProcedure name params body = Procedure name [SimpleEquation params body] pattern SimpleMethod name params body = Method name [SimpleEquation params body] pattern MuTrue = MuBool True pattern MuFalse = MuBool False pattern Subroutine name equations <- (extractSubroutine -> Just (name, equations)) pattern Clause name patterns expressions <- (extractClause -> Just (name, patterns, expressions)) pattern Call operation arguments <- (extractCall -> Just (operation, arguments)) pattern Params params <- (extractParams -> Just params) equationParams :: Equation -> [Pattern] equationParams (Equation p _) = p extractSubroutine :: Expression -> Maybe (Identifier, [Equation]) extractSubroutine (Function name equations) = Just (name, equations) extractSubroutine (Procedure name equations) = Just (name, equations) extractSubroutine (Method name equations) = Just (name, equations) extractSubroutine _ = Nothing extractParams :: Expression -> Maybe ([Pattern]) extractParams (Subroutine _ equations) = Just (equationParams.head $ equations) extractParams (Clause _ params _) = Just params extractParams _ = Nothing extractCall :: Expression -> Maybe (Expression, [Expression]) extractCall (Application op args) = Just (op, args) extractCall (Send receptor op args) = Just (op, (receptor:args)) extractCall _ = Nothing extractClause :: Expression -> Maybe (Identifier, [Pattern], [Expression]) extractClause (Fact name patterns) = Just (name, patterns, []) extractClause (Rule name patterns expressions) = Just (name, patterns, expressions) extractClause _ = Nothing