{-# 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 }