packages feed

jl-0.1.0: src/JL/Types.hs

{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE LambdaCase #-}
-- |

module JL.Types where

import Control.Exception
import Data.Data
import qualified Data.HashMap.Strict as HM
import Data.HashMap.Strict (HashMap)
import Data.Scientific
import Data.Text (Text)
import Data.Vector (Vector)
import Text.Parsec.Error

data ParseException
  = TokenizerError !ParseError
  | ParserError !ParseError
 deriving (Typeable, Show)
instance Exception ParseException

-- | A type.
data Type
  = VariableType !TypeVariable
  | FunctionType !Type !Type
  | JSONType
  deriving (Ord, Eq, Show)

-- | A parsed expression.
data Expression
  = VariableExpression Variable
  | LambdaExpression Variable Expression
  | ApplicationExpression Expression Expression
  | InfixExpression Expression Variable Expression
  | IfExpression Expression Expression Expression
  | SubscriptExpression Subscripted [Subscript]
  | RecordExpression (HashMap Text Expression)
  | ArrayExpression (Vector Expression)
  | ConstantExpression Constant
  deriving (Show, Eq)

data Subscripted
  = WildcardSubscripted
  | ExpressionSubscripted Expression
  deriving (Show, Eq)

data Subscript
  = PropertySubscript Text
  | ExpressionSubscript Expression
  deriving (Show, Eq)

-- | Desugared core AST.
data Core
  = VariableCore Variable
  | LambdaCore Variable Core
  | ApplicationCore Core Core
  | IfCore Core Core Core
  | EvalCore (Core -> Core)
  | RecordCore (HashMap Text Core)
  | ArrayCore (Vector Core)
  | ConstantCore Constant

data Compare
  = ConstantCompare Constant
  | VectorCompare (Vector Compare)
  | RecordCompare [(Text, Compare)]
  deriving (Eq, Ord)

coreToCompare :: Core -> Compare
coreToCompare =
  \case
    ConstantCore c -> ConstantCompare c
    ArrayCore cs -> VectorCompare (fmap coreToCompare cs)
    RecordCore cs -> RecordCompare (HM.toList (fmap coreToCompare cs))
    _ -> error "Cannot compare that value for sorting"

-- | A self-evaluating constant.
data Constant
  = StringConstant Text
  | NumberConstant Scientific
  | BoolConstant Bool
  | NullConstant
  deriving (Show, Eq, Ord)

-- | A type variable, generated by the type system.
newtype TypeVariable =
  TypeVariable Int
  deriving (Show, Eq, Ord)

-- | A value variable, inputted by the programmer.
newtype Variable =
  Variable Text
  deriving (Show, Eq, Ord)

data Token
  = If
  | Then
  | Else
  | Case
  | Of
  | Backslash
  | RightArrow
  | Dollar
  | OpenParen
  | CloseParen
  | OpenBracket
  | CloseBracket
  | VariableToken !Text
  | StringToken !Text
  | Operator !Text
  | Period
  | Comma
  | Integer !Integer
  | Decimal !Double
  | OpenBrace
  | CloseBrace
  | Colon
  | NonIndentedNewline
  | Bar
  | TrueToken
  | FalseToken
  | NullToken
  deriving (Eq, Ord, Show)

data Location = Location
  { locationStartLine :: !Int
  , locationStartColumn :: !Int
  , locationEndLine :: !Int
  , locationEndColumn :: !Int
  } deriving (Show, Eq)

data Definition = Definition
  { definitionName :: Variable
  , definitionDoc :: Text
  , definitionType :: Type
  , definitionCore :: Core
  }