{-# LANGUAGE DeriveFunctor #-} module AST where import Data.Text (Text) import Data.Scientific (Scientific) data Type = Bool | Char | String -- Integer types. | SInt8 | UInt8 | SInt16 | UInt16 | SInt32 | UInt32 | SInt64 | UInt64 -- Floating-point numbers. | Float32 | Float64 | Function Type Type | Forall Text Type | TypeVar Text | TypeConstructor Text [Type] | Tuple [Type] | List Type deriving (Eq, Show) -- | An expression. data Expr a = Var Text a -- ^ A named variable. -- Literals. | BoolLiteral Bool a -- ^ A boolean literal. | NumLiteral Scientific a | CharLiteral Char a | StringLiteral Text a | TupleLiteral [Expr a] a | ListLiteral [Expr a] a -- Function application. | Application (Expr a) (Expr a) a -- Basic arithmetic operations. Specialised case of function application to easily allow potential optimisations. | Add (Expr a) (Expr a) a | Sub (Expr a) (Expr a) a | Mul (Expr a) (Expr a) a | Div (Expr a) (Expr a) a | Mod (Expr a) (Expr a) a | Neg (Expr a) a -- Basic comparison operations. Specialised case of function application to easily allow potential optimisations. | Eq (Expr a) (Expr a) a | Neq (Expr a) (Expr a) a | Gt (Expr a) (Expr a) a | Geq (Expr a) (Expr a) a | Lt (Expr a) (Expr a) a | Leq (Expr a) (Expr a) a -- Logical operations. Specialised case of function application to easily allow potential optimisations. | Or (Expr a) (Expr a) a | And (Expr a) (Expr a) a | Not (Expr a) a -- Array/list indexing. Specialised case of function application to easily allow potential optimisations. | IndexExpr (Expr a) (Expr a) a | Conditional -- ^ Conditional expression. (Expr a) -- ^ Condition. (Expr a) -- ^ Then-branch. (Expr a) -- ^ Else-branch. a | Block [Statement a] a -- ^ A block of statements returning a value. | Let -- ^ Binding an expression to a named variable. (PurePattern a) -- ^ Bound variable name. (Expr a) -- ^ Expression to bind to. (Expr a) -- ^ Expression where bound variable is used. a | Typed (Expr a) Type a -- ^ Expression with a type annotation. deriving (Eq, Show, Functor) -- | A statement. data Statement a = If (Expr a) (Statement a) a | Else (Statement a) a | While (Expr a) (Statement a) a | Expr (Expr a) a -- ^ Using an expression as a statement, discarding the value. | StatementBlock [Statement a] a | VariableDef Text a | Assign (AssignablePattern a) (Expr a) a | Return (Expr a) a deriving (Eq, Show, Functor) data PurePattern a = VarPattern Text a | ConstructorDeconstruct Text [PurePattern a] a -- Separate patterns for lists and tuples to easily allow potential optimisations. | TupleDeconstruct [PurePattern a] a | ListDeconstruct [PurePattern a] a deriving (Eq, Show, Functor) data AssignablePattern a = FromPurePattern (PurePattern a) a | IndexPattern Text (Expr a) a deriving (Eq, Show, Functor) data Constructor a = Constructor Text [Type] a deriving (Eq, Show, Functor) data TopLevelStatement a = TypeDef Text [Text] [Constructor a] a -- ^ Datatype definition with name, type vars, constructors of name and fields. | FunctionDef Text [Text] (Expr a) a -- ^ Function definition with name and parameters. | TypeAnnotation Text Type a -- ^ Type annotation for named function. deriving (Eq, Show, Functor) type Program a = [TopLevelStatement a]