egison-5.0.0: hs-src/Language/Egison/AST.hs
{-# LANGUAGE DeriveTraversable #-}
{- |
Module : Language.Egison.AST
Licence : MIT
This module defines the syntax of Egison.
-}
module Language.Egison.AST
( TopExpr (..)
, ConstantExpr (..)
, Expr (..)
, Pattern (..)
, VarWithIndices (..)
, makeApply
, Arg (..)
, ArgPattern (..)
, IndexExpr (..)
, VarIndex (..)
, PMMode (..)
, BindingExpr (..)
, MatchClause
, PatternDef (..)
, LoopRange (..)
, PrimitivePatPattern (..)
, PDPatternBase (..)
, PrimitiveDataPattern
, Op (..)
, Assoc (..)
, reservedExprOp
, reservedPatternOp
, findOpFrom
, stringToVarWithIndices
, extractNameFromVarWithIndices
-- Type annotations
, TypeExpr (..)
, TensorShapeExpr (..)
, ShapeDim (..)
, TensorIndexExpr (..)
, TypedParam (..)
, TypedVarWithIndices (..)
-- Inductive data types
, InductiveConstructor (..)
-- Pattern inductive types
, PatternConstructor (..)
-- Type classes
, ClassDecl (..)
, ClassMethod (..)
, InstanceDecl (..)
, InstanceMethod (..)
, ConstraintExpr (..)
) where
import Data.List (find)
import Data.Maybe (fromJust)
import Data.Text (Text)
data TopExpr
= Define VarWithIndices Expr
| DefineWithType TypedVarWithIndices Expr -- ^ Definition with type annotation
| Test Expr
| Execute Expr
-- temporary : we will replace load to import and export
| LoadFile String
| Load String
| InfixDecl Bool Op -- True for pattern infix; False for expression infix
| InductiveDecl String [String] [InductiveConstructor]
-- ^ Inductive data type declaration with type parameters
-- e.g., inductive Ordering := | Less | Equal | Greater
-- inductive Maybe a := | Nothing | Just a
-- String: type name, [String]: type parameters, [InductiveConstructor]: constructors
| ClassDeclExpr ClassDecl
-- ^ Type class declaration
-- e.g., class Eq a where (==) (x: a) (y: a) : Bool
| InstanceDeclExpr InstanceDecl
-- ^ Type class instance declaration
-- e.g., instance Eq Integer where (==) x y := x = y
| PatternInductiveDecl String [String] [PatternConstructor]
-- ^ Pattern inductive type declaration
-- e.g., inductive pattern MyList a := | myNil | myCons a (MyList a)
-- String: pattern type name, [String]: type parameters, [PatternConstructor]: constructors
| PatternFunctionDecl String [String] [(String, TypeExpr)] TypeExpr Pattern
-- ^ Pattern function declaration
-- e.g., def pattern twin {a} (p1 : a) (p2 : MyList a) : MyList a := ...
-- String: function name, [String]: type parameters, [(String, TypeExpr)]: parameters, TypeExpr: return type, Pattern: body
| DeclareSymbol [String] (Maybe TypeExpr)
-- ^ Symbol declaration
-- e.g., declare symbol a11, a12, a21, a22
-- declare symbol x, y, z : Float
-- [String]: symbol names, Maybe TypeExpr: optional type (defaults to Integer)
deriving Show
-- | Type class declaration
-- e.g., class Eq a where ...
-- class Eq a => Ord a where ...
data ClassDecl = ClassDecl
{ className :: String -- ^ Class name (e.g., "Eq", "Ord")
, classTypeParams :: [String] -- ^ Type parameters (e.g., ["a"])
, classSuperclasses :: [ConstraintExpr] -- ^ Superclass constraints (e.g., [Eq a] for Ord)
, classMethods :: [ClassMethod] -- ^ Method declarations
} deriving Show
-- | Type class method declaration
-- e.g., (==) (x: a) (y: a) : Bool
-- (/=) (x: a) (y: a) : Bool := not (x == y)
data ClassMethod = ClassMethod
{ methodName :: String -- ^ Method name (e.g., "==")
, methodParams :: [TypedParam] -- ^ Method parameters with types
, methodRetType :: TypeExpr -- ^ Return type
, methodDefault :: Maybe Expr -- ^ Optional default implementation
} deriving Show
-- | Type class instance declaration
-- e.g., instance Eq Integer where ...
-- instance Eq a => Eq [a] where ...
data InstanceDecl = InstanceDecl
{ instanceConstraints :: [ConstraintExpr] -- ^ Instance constraints (e.g., [Eq a] for Eq [a])
, instanceClass :: String -- ^ Class name (e.g., "Eq")
, instanceTypes :: [TypeExpr] -- ^ Instance types (e.g., [Integer] or [[a]])
, instanceMethods :: [InstanceMethod] -- ^ Method implementations
} deriving Show
-- | Instance method implementation
-- e.g., (==) x y := x = y
data InstanceMethod = InstanceMethod
{ instMethodName :: String -- ^ Method name
, instMethodParams :: [String] -- ^ Parameter names
, instMethodBody :: Expr -- ^ Method body
} deriving Show
-- | Type constraint expression
-- e.g., Eq a, Ord a
data ConstraintExpr = ConstraintExpr
{ constraintClass :: String -- ^ Class name
, constraintTypes :: [TypeExpr] -- ^ Type arguments
} deriving (Show, Eq)
-- | Constructor for inductive data type
-- e.g., Less, S Nat, Node Tree Tree
data InductiveConstructor = InductiveConstructor
{ inductiveCtorName :: String -- ^ Constructor name (e.g., "Less", "S", "Node")
, inductiveCtorArgs :: [TypeExpr] -- ^ Constructor argument types (e.g., [], [Nat], [Tree, Tree])
} deriving (Show, Eq)
-- | Constructor for pattern inductive type
-- e.g., myNil, myCons a (MyList a)
data PatternConstructor = PatternConstructor
{ patternCtorName :: String -- ^ Pattern constructor name (e.g., "myNil", "myCons")
, patternCtorArgs :: [TypeExpr] -- ^ Pattern constructor argument types (e.g., [], [a, MyList a])
} deriving (Show, Eq)
data ConstantExpr
= CharExpr Char
| StringExpr Text
| BoolExpr Bool
| IntegerExpr Integer
| FloatExpr Double
| SomethingExpr
| UndefinedExpr
deriving Show
data Expr
= ConstantExpr ConstantExpr
| VarExpr String
| FreshVarExpr
| IndexedExpr Bool Expr [IndexExpr Expr] -- True -> delete old index and append new one
| SubrefsExpr Bool Expr Expr
| SuprefsExpr Bool Expr Expr
| UserrefsExpr Bool Expr Expr
| TupleExpr [Expr]
| CollectionExpr [Expr]
| ConsExpr Expr Expr
| JoinExpr Expr Expr
| HashExpr [(Expr, Expr)]
| VectorExpr [Expr]
| LambdaExpr [Arg ArgPattern] Expr
| LambdaExpr' [Arg VarWithIndices] Expr
| TypedLambdaExpr [(String, TypeExpr)] TypeExpr Expr -- ^ Lambda with typed parameters and return type
| MemoizedLambdaExpr [String] Expr
| TypedMemoizedLambdaExpr [TypedParam] TypeExpr Expr -- ^ Memoized lambda with typed parameters
| CambdaExpr String Expr
| PatternFunctionExpr [String] Pattern
| IfExpr Expr Expr Expr
| LetExpr [BindingExpr] Expr
| LetRecExpr [BindingExpr] Expr
| WithSymbolsExpr [String] Expr
| MatchExpr PMMode Expr Expr [MatchClause]
| MatchAllExpr PMMode Expr Expr [MatchClause]
| MatchLambdaExpr Expr [MatchClause]
| MatchAllLambdaExpr Expr [MatchClause]
| MatcherExpr [PatternDef]
| AlgebraicDataMatcherExpr [(String, [Expr])]
| QuoteExpr Expr
| QuoteSymbolExpr Expr
| WedgeApplyExpr Expr [Expr]
| DoExpr [BindingExpr] Expr
| PrefixExpr String Expr
| InfixExpr Op Expr Expr
| SectionExpr Op (Maybe Expr) (Maybe Expr) -- There cannot be 'SectionExpr op (Just _) (Just _)'
| SeqExpr Expr Expr
| ApplyExpr Expr [Expr]
| AnonParamFuncExpr Integer Expr -- e.g. 2#2, 3#$1, 2#($1 + $2)
| AnonTupleParamFuncExpr Integer Expr -- e.g. (2)#2, (3)#$1, (2)#($1 + $2)
| AnonListParamFuncExpr Integer Expr -- e.g. [2]#2, [3]#$1, [2]#($1 + $2)
| AnonParamExpr Integer -- e.g. $1, $2
| GenerateTensorExpr Expr Expr
| TensorExpr Expr Expr
| TensorContractExpr Expr
| TensorMapExpr Expr Expr
| TensorMap2Expr Expr Expr Expr
| TransposeExpr Expr Expr
| FlipIndicesExpr Expr
| FunctionExpr [String]
| TypeAnnotation Expr TypeExpr -- ^ Expression with type annotation (expr : type)
deriving Show
data VarWithIndices = VarWithIndices String [VarIndex]
deriving (Show, Eq)
data Arg a
= Arg a
| InvertedArg a
deriving Show
data ArgPattern
= APWildCard
| APPatVar VarWithIndices
| APInductivePat String [Arg ArgPattern]
| APTuplePat [Arg ArgPattern]
| APEmptyPat
| APConsPat (Arg ArgPattern) ArgPattern
| APSnocPat ArgPattern (Arg ArgPattern)
deriving Show
data VarIndex
= VSubscript String
| VSuperscript String
| VMultiSubscript String Integer String -- _(a_1)..._(a_n) -> VMultiSubscript "a" 1 "n"
| VMultiSuperscript String Integer String -- ~(a_1)...~(a_n) -> VMultiSuperscript "a" 1 "n"
| VGroupScripts [VarIndex]
| VSymmScripts [VarIndex]
| VAntiSymmScripts [VarIndex]
deriving (Show, Eq)
data IndexExpr a
= Subscript a
| Superscript a
| SupSubscript a
| MultiSubscript a a
| MultiSuperscript a a
| Userscript a
deriving (Show, Eq, Functor, Foldable, Traversable)
data PMMode = BFSMode | DFSMode
deriving Show
data BindingExpr
= Bind PrimitiveDataPattern Expr
| BindWithIndices VarWithIndices Expr
| BindWithType TypedVarWithIndices Expr -- ^ Binding with type annotation (for where clauses)
deriving Show
type MatchClause = (Pattern, Expr)
-- | Pattern definition in a matcher (with optional type class constraints)
data PatternDef = PatternDef
{ patDefPattern :: PrimitivePatPattern
, patDefMatcher :: Expr
, patDefClauses :: [(PrimitiveDataPattern, Expr)]
} deriving Show
data Pattern
= WildCard
| PatVar String
| ValuePat Expr
| PredPat Expr
| IndexedPat Pattern [Expr]
| LetPat [BindingExpr] Pattern
| InfixPat Op Pattern Pattern -- Includes AndPat,OrPat,InductivePat(cons/join)
| NotPat Pattern
| AndPat Pattern Pattern
| OrPat Pattern Pattern
| ForallPat Pattern Pattern
| TuplePat [Pattern]
| InductivePat String [Pattern]
| LoopPat String LoopRange Pattern Pattern
| ContPat
| PApplyPat Expr [Pattern]
| VarPat String
| InductiveOrPApplyPat String [Pattern]
| SeqNilPat
| SeqConsPat Pattern Pattern
| LaterPatVar
-- For symbolic computing
| DApplyPat Pattern [Pattern]
deriving Show
data LoopRange = LoopRange Expr Expr Pattern
deriving Show
data PrimitivePatPattern
= PPWildCard
| PPPatVar
| PPValuePat String -- Variable name
| PPInductivePat String [PrimitivePatPattern]
| PPTuplePat [PrimitivePatPattern]
deriving Show
data PDPatternBase var
= PDWildCard
| PDPatVar var
| PDInductivePat String [PDPatternBase var]
| PDTuplePat [PDPatternBase var]
| PDEmptyPat
| PDConsPat (PDPatternBase var) (PDPatternBase var)
| PDSnocPat (PDPatternBase var) (PDPatternBase var)
| PDConstantPat ConstantExpr
-- ScalarData (MathExpr) primitive patterns
| PDDivPat (PDPatternBase var) (PDPatternBase var) -- Div: ScalarData -> PolyExpr, PolyExpr
| PDPlusPat (PDPatternBase var) -- Plus: PolyExpr -> [TermExpr]
| PDTermPat (PDPatternBase var) (PDPatternBase var) -- Term: TermExpr -> Integer, [(SymbolExpr, Integer)]
| PDSymbolPat (PDPatternBase var) (PDPatternBase var) -- Symbol: SymbolExpr -> String, [IndexExpr]
| PDApply1Pat (PDPatternBase var) (PDPatternBase var) -- Apply1: SymbolExpr -> MathExpr, MathExpr
| PDApply2Pat (PDPatternBase var) (PDPatternBase var) (PDPatternBase var) -- Apply2
| PDApply3Pat (PDPatternBase var) (PDPatternBase var) (PDPatternBase var) (PDPatternBase var) -- Apply3
| PDApply4Pat (PDPatternBase var) (PDPatternBase var) (PDPatternBase var) (PDPatternBase var) (PDPatternBase var) -- Apply4
| PDQuotePat (PDPatternBase var) -- Quote: SymbolExpr -> MathExpr
| PDFunctionPat (PDPatternBase var) (PDPatternBase var) -- Function: SymbolExpr -> MathExpr, [MathExpr]
| PDSubPat (PDPatternBase var) -- Sub: IndexExpr -> MathExpr
| PDSupPat (PDPatternBase var) -- Sup: IndexExpr -> MathExpr
| PDUserPat (PDPatternBase var) -- User: IndexExpr -> MathExpr
deriving (Functor, Foldable, Show)
type PrimitiveDataPattern = PDPatternBase String
data Op
= Op { repr :: String -- syntastic representation
, priority :: Int
, assoc :: Assoc
, isWedge :: Bool -- True if operator is prefixed with '!'. Only used for expression infix.
}
deriving (Eq, Ord, Show)
data Assoc
= InfixL
| InfixR
| InfixN
| Prefix
deriving (Eq, Ord)
instance Show Assoc where
show InfixL = "infixl"
show InfixR = "infixr"
show InfixN = "infix"
show Prefix = "prefix"
reservedExprOp :: [Op]
reservedExprOp =
[ Op "!" 8 Prefix False -- Wedge and InvertedArg prefix
, Op "-" 7 Prefix False -- Negate
, Op "%" 7 InfixL False -- primitive function
, Op "++" 5 InfixR False
, Op "::" 5 InfixR False
, Op "==" 4 InfixL False -- equality (from type class)
, Op "/=" 4 InfixL False -- inequality (from type class)
, Op "=" 4 InfixL False -- primitive function
, Op "<=" 4 InfixL False -- primitive function
, Op ">=" 4 InfixL False -- primitive function
, Op "<" 4 InfixL False -- primitive function
, Op ">" 4 InfixL False -- primitive function
, Op "&&" 3 InfixR False -- logical and (from base)
, Op "||" 2 InfixR False -- logical or (from base)
, Op "$" 0 InfixR False -- right-associative lowest-priority (application)
, Op "+" 6 InfixL False
, Op "-" 6 InfixL False
, Op "*" 7 InfixL False
, Op "/" 7 InfixL False
, Op "^" 8 InfixL False
, Op "+'" 6 InfixL False
, Op "-'" 6 InfixL False
, Op "*'" 7 InfixL False
, Op "/'" 7 InfixL False
, Op "^'" 8 InfixL False
, Op "∧" 7 InfixL False
, Op "." 7 InfixL False
, Op ".'" 7 InfixL False
]
reservedPatternOp :: [Op]
reservedPatternOp =
[ Op "++" 5 InfixR False
, Op "*:" 5 InfixL False
, Op "+" 7 InfixR False
, Op "*" 8 InfixR False
, Op "/" 8 InfixN False
, Op "^" 9 InfixN False
, Op "::" 6 InfixR False -- required for desugaring collection pattern (priority 6 > ++ priority 5)
, Op "&" 3 InfixR False
, Op "|" 2 InfixR False
]
findOpFrom :: String -> [Op] -> Op
findOpFrom op table = fromJust $ find ((== op) . repr) table
makeApply :: String -> [Expr] -> Expr
makeApply func args = ApplyExpr (VarExpr func) args
stringToVarWithIndices :: String -> VarWithIndices
stringToVarWithIndices name = VarWithIndices name []
extractNameFromVarWithIndices :: VarWithIndices -> String
extractNameFromVarWithIndices (VarWithIndices name _) = name
--
-- Type expressions (for type annotations)
--
-- | Type expression in source code
data TypeExpr
= TEInt -- ^ Integer (= MathExpr)
| TEMathExpr -- ^ MathExpr (= Integer)
| TEFloat -- ^ Float
| TEBool -- ^ Bool
| TEChar -- ^ Char
| TEString -- ^ String
| TEVar String -- ^ Type variable, e.g., a
| TEList TypeExpr -- ^ List type, e.g., [a]
| TETuple [TypeExpr] -- ^ Tuple type, e.g., (a, b)
| TEFun TypeExpr TypeExpr -- ^ Function type, e.g., a -> b
| TEMatcher TypeExpr -- ^ Matcher type
| TEPattern TypeExpr -- ^ Pattern type, e.g., Pattern a
| TEIO TypeExpr -- ^ IO type, e.g., IO ()
| TETensor TypeExpr -- ^ Tensor type, e.g., Tensor a
| TEVector TypeExpr -- ^ Vector type, e.g., Vector a (1D tensor)
| TEMatrix TypeExpr -- ^ Matrix type, e.g., Matrix a (2D tensor)
| TEDiffForm TypeExpr -- ^ DiffForm type, e.g., DiffForm a (differential form, alias for Tensor)
| TEApp TypeExpr [TypeExpr] -- ^ Type application, e.g., List a
| TEConstrained [ConstraintExpr] TypeExpr
-- ^ Constrained type, e.g., Eq a => a
deriving (Show, Eq)
-- | Tensor shape expression
data TensorShapeExpr
= TSLit [Integer] -- ^ Concrete shape, e.g., [2, 2]
| TSVar String -- ^ Shape variable
| TSMixed [ShapeDim] -- ^ Mixed shape, e.g., [n, m, 2]
deriving (Show, Eq)
-- | Shape dimension (can be concrete or variable)
data ShapeDim
= SDLit Integer -- ^ Concrete dimension, e.g., 2
| SDVar String -- ^ Dimension variable, e.g., n
deriving (Show, Eq)
-- | Tensor index expression
data TensorIndexExpr
= TISub String -- ^ Subscript, e.g., _i
| TISup String -- ^ Superscript, e.g., ~i
| TIPlaceholderSub -- ^ Subscript placeholder, _#
| TIPlaceholderSup -- ^ Superscript placeholder, ~#
deriving (Show, Eq)
-- | Typed parameter pattern
data TypedParam
= TPVar String TypeExpr -- ^ Simple variable with type: (x: a)
| TPInvertedVar String TypeExpr -- ^ Inverted variable with type: (!x: a)
| TPTuple [TypedParam] -- ^ Tuple pattern: ((x: a), (y: b)) or (x: a, y: b)
| TPWildcard TypeExpr -- ^ Wildcard with type: (_: a)
| TPUntypedVar String -- ^ Untyped variable in tuple: x (inferred)
| TPUntypedWildcard -- ^ Untyped wildcard: _
deriving (Show, Eq)
-- | Variable with type annotation
data TypedVarWithIndices = TypedVarWithIndices
{ typedVarName :: String
, typedVarIndices :: [VarIndex]
, typedVarConstraints :: [ConstraintExpr] -- ^ Type class constraints
, typedVarParams :: [TypedParam] -- ^ Typed parameters (can include tuples)
, typedVarRetType :: TypeExpr -- ^ Return type
} deriving (Show, Eq)