{-# 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, Int -> ParseException -> ShowS
[ParseException] -> ShowS
ParseException -> String
(Int -> ParseException -> ShowS)
-> (ParseException -> String)
-> ([ParseException] -> ShowS)
-> Show ParseException
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [ParseException] -> ShowS
$cshowList :: [ParseException] -> ShowS
show :: ParseException -> String
$cshow :: ParseException -> String
showsPrec :: Int -> ParseException -> ShowS
$cshowsPrec :: Int -> ParseException -> ShowS
Show)
instance Exception ParseException

-- | A type.
data Type
  = VariableType !TypeVariable
  | FunctionType !Type !Type
  | JSONType
  deriving (Eq Type
Eq Type
-> (Type -> Type -> Ordering)
-> (Type -> Type -> Bool)
-> (Type -> Type -> Bool)
-> (Type -> Type -> Bool)
-> (Type -> Type -> Bool)
-> (Type -> Type -> Type)
-> (Type -> Type -> Type)
-> Ord Type
Type -> Type -> Bool
Type -> Type -> Ordering
Type -> Type -> Type
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: Type -> Type -> Type
$cmin :: Type -> Type -> Type
max :: Type -> Type -> Type
$cmax :: Type -> Type -> Type
>= :: Type -> Type -> Bool
$c>= :: Type -> Type -> Bool
> :: Type -> Type -> Bool
$c> :: Type -> Type -> Bool
<= :: Type -> Type -> Bool
$c<= :: Type -> Type -> Bool
< :: Type -> Type -> Bool
$c< :: Type -> Type -> Bool
compare :: Type -> Type -> Ordering
$ccompare :: Type -> Type -> Ordering
$cp1Ord :: Eq Type
Ord, Type -> Type -> Bool
(Type -> Type -> Bool) -> (Type -> Type -> Bool) -> Eq Type
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Type -> Type -> Bool
$c/= :: Type -> Type -> Bool
== :: Type -> Type -> Bool
$c== :: Type -> Type -> Bool
Eq, Int -> Type -> ShowS
[Type] -> ShowS
Type -> String
(Int -> Type -> ShowS)
-> (Type -> String) -> ([Type] -> ShowS) -> Show Type
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Type] -> ShowS
$cshowList :: [Type] -> ShowS
show :: Type -> String
$cshow :: Type -> String
showsPrec :: Int -> Type -> ShowS
$cshowsPrec :: Int -> Type -> ShowS
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 (Int -> Expression -> ShowS
[Expression] -> ShowS
Expression -> String
(Int -> Expression -> ShowS)
-> (Expression -> String)
-> ([Expression] -> ShowS)
-> Show Expression
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Expression] -> ShowS
$cshowList :: [Expression] -> ShowS
show :: Expression -> String
$cshow :: Expression -> String
showsPrec :: Int -> Expression -> ShowS
$cshowsPrec :: Int -> Expression -> ShowS
Show, Expression -> Expression -> Bool
(Expression -> Expression -> Bool)
-> (Expression -> Expression -> Bool) -> Eq Expression
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Expression -> Expression -> Bool
$c/= :: Expression -> Expression -> Bool
== :: Expression -> Expression -> Bool
$c== :: Expression -> Expression -> Bool
Eq)

data Subscripted
  = WildcardSubscripted
  | ExpressionSubscripted Expression
  deriving (Int -> Subscripted -> ShowS
[Subscripted] -> ShowS
Subscripted -> String
(Int -> Subscripted -> ShowS)
-> (Subscripted -> String)
-> ([Subscripted] -> ShowS)
-> Show Subscripted
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Subscripted] -> ShowS
$cshowList :: [Subscripted] -> ShowS
show :: Subscripted -> String
$cshow :: Subscripted -> String
showsPrec :: Int -> Subscripted -> ShowS
$cshowsPrec :: Int -> Subscripted -> ShowS
Show, Subscripted -> Subscripted -> Bool
(Subscripted -> Subscripted -> Bool)
-> (Subscripted -> Subscripted -> Bool) -> Eq Subscripted
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Subscripted -> Subscripted -> Bool
$c/= :: Subscripted -> Subscripted -> Bool
== :: Subscripted -> Subscripted -> Bool
$c== :: Subscripted -> Subscripted -> Bool
Eq)

data Subscript
  = PropertySubscript Text
  | ExpressionSubscript Expression
  deriving (Int -> Subscript -> ShowS
[Subscript] -> ShowS
Subscript -> String
(Int -> Subscript -> ShowS)
-> (Subscript -> String)
-> ([Subscript] -> ShowS)
-> Show Subscript
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Subscript] -> ShowS
$cshowList :: [Subscript] -> ShowS
show :: Subscript -> String
$cshow :: Subscript -> String
showsPrec :: Int -> Subscript -> ShowS
$cshowsPrec :: Int -> Subscript -> ShowS
Show, Subscript -> Subscript -> Bool
(Subscript -> Subscript -> Bool)
-> (Subscript -> Subscript -> Bool) -> Eq Subscript
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Subscript -> Subscript -> Bool
$c/= :: Subscript -> Subscript -> Bool
== :: Subscript -> Subscript -> Bool
$c== :: Subscript -> Subscript -> Bool
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 (Compare -> Compare -> Bool
(Compare -> Compare -> Bool)
-> (Compare -> Compare -> Bool) -> Eq Compare
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Compare -> Compare -> Bool
$c/= :: Compare -> Compare -> Bool
== :: Compare -> Compare -> Bool
$c== :: Compare -> Compare -> Bool
Eq, Eq Compare
Eq Compare
-> (Compare -> Compare -> Ordering)
-> (Compare -> Compare -> Bool)
-> (Compare -> Compare -> Bool)
-> (Compare -> Compare -> Bool)
-> (Compare -> Compare -> Bool)
-> (Compare -> Compare -> Compare)
-> (Compare -> Compare -> Compare)
-> Ord Compare
Compare -> Compare -> Bool
Compare -> Compare -> Ordering
Compare -> Compare -> Compare
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: Compare -> Compare -> Compare
$cmin :: Compare -> Compare -> Compare
max :: Compare -> Compare -> Compare
$cmax :: Compare -> Compare -> Compare
>= :: Compare -> Compare -> Bool
$c>= :: Compare -> Compare -> Bool
> :: Compare -> Compare -> Bool
$c> :: Compare -> Compare -> Bool
<= :: Compare -> Compare -> Bool
$c<= :: Compare -> Compare -> Bool
< :: Compare -> Compare -> Bool
$c< :: Compare -> Compare -> Bool
compare :: Compare -> Compare -> Ordering
$ccompare :: Compare -> Compare -> Ordering
$cp1Ord :: Eq Compare
Ord)

coreToCompare :: Core -> Compare
coreToCompare :: Core -> Compare
coreToCompare =
  \case
    ConstantCore Constant
c -> Constant -> Compare
ConstantCompare Constant
c
    ArrayCore Vector Core
cs -> Vector Compare -> Compare
VectorCompare ((Core -> Compare) -> Vector Core -> Vector Compare
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Core -> Compare
coreToCompare Vector Core
cs)
    RecordCore HashMap Text Core
cs -> [(Text, Compare)] -> Compare
RecordCompare (HashMap Text Compare -> [(Text, Compare)]
forall k v. HashMap k v -> [(k, v)]
HM.toList ((Core -> Compare) -> HashMap Text Core -> HashMap Text Compare
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Core -> Compare
coreToCompare HashMap Text Core
cs))
    Core
_ -> String -> Compare
forall a. HasCallStack => String -> a
error String
"Cannot compare that value for sorting"

-- | A self-evaluating constant.
data Constant
  = StringConstant Text
  | NumberConstant Scientific
  | BoolConstant Bool
  | NullConstant
  deriving (Int -> Constant -> ShowS
[Constant] -> ShowS
Constant -> String
(Int -> Constant -> ShowS)
-> (Constant -> String) -> ([Constant] -> ShowS) -> Show Constant
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Constant] -> ShowS
$cshowList :: [Constant] -> ShowS
show :: Constant -> String
$cshow :: Constant -> String
showsPrec :: Int -> Constant -> ShowS
$cshowsPrec :: Int -> Constant -> ShowS
Show, Constant -> Constant -> Bool
(Constant -> Constant -> Bool)
-> (Constant -> Constant -> Bool) -> Eq Constant
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Constant -> Constant -> Bool
$c/= :: Constant -> Constant -> Bool
== :: Constant -> Constant -> Bool
$c== :: Constant -> Constant -> Bool
Eq, Eq Constant
Eq Constant
-> (Constant -> Constant -> Ordering)
-> (Constant -> Constant -> Bool)
-> (Constant -> Constant -> Bool)
-> (Constant -> Constant -> Bool)
-> (Constant -> Constant -> Bool)
-> (Constant -> Constant -> Constant)
-> (Constant -> Constant -> Constant)
-> Ord Constant
Constant -> Constant -> Bool
Constant -> Constant -> Ordering
Constant -> Constant -> Constant
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: Constant -> Constant -> Constant
$cmin :: Constant -> Constant -> Constant
max :: Constant -> Constant -> Constant
$cmax :: Constant -> Constant -> Constant
>= :: Constant -> Constant -> Bool
$c>= :: Constant -> Constant -> Bool
> :: Constant -> Constant -> Bool
$c> :: Constant -> Constant -> Bool
<= :: Constant -> Constant -> Bool
$c<= :: Constant -> Constant -> Bool
< :: Constant -> Constant -> Bool
$c< :: Constant -> Constant -> Bool
compare :: Constant -> Constant -> Ordering
$ccompare :: Constant -> Constant -> Ordering
$cp1Ord :: Eq Constant
Ord)

-- | A type variable, generated by the type system.
newtype TypeVariable =
  TypeVariable Int
  deriving (Int -> TypeVariable -> ShowS
[TypeVariable] -> ShowS
TypeVariable -> String
(Int -> TypeVariable -> ShowS)
-> (TypeVariable -> String)
-> ([TypeVariable] -> ShowS)
-> Show TypeVariable
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [TypeVariable] -> ShowS
$cshowList :: [TypeVariable] -> ShowS
show :: TypeVariable -> String
$cshow :: TypeVariable -> String
showsPrec :: Int -> TypeVariable -> ShowS
$cshowsPrec :: Int -> TypeVariable -> ShowS
Show, TypeVariable -> TypeVariable -> Bool
(TypeVariable -> TypeVariable -> Bool)
-> (TypeVariable -> TypeVariable -> Bool) -> Eq TypeVariable
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: TypeVariable -> TypeVariable -> Bool
$c/= :: TypeVariable -> TypeVariable -> Bool
== :: TypeVariable -> TypeVariable -> Bool
$c== :: TypeVariable -> TypeVariable -> Bool
Eq, Eq TypeVariable
Eq TypeVariable
-> (TypeVariable -> TypeVariable -> Ordering)
-> (TypeVariable -> TypeVariable -> Bool)
-> (TypeVariable -> TypeVariable -> Bool)
-> (TypeVariable -> TypeVariable -> Bool)
-> (TypeVariable -> TypeVariable -> Bool)
-> (TypeVariable -> TypeVariable -> TypeVariable)
-> (TypeVariable -> TypeVariable -> TypeVariable)
-> Ord TypeVariable
TypeVariable -> TypeVariable -> Bool
TypeVariable -> TypeVariable -> Ordering
TypeVariable -> TypeVariable -> TypeVariable
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: TypeVariable -> TypeVariable -> TypeVariable
$cmin :: TypeVariable -> TypeVariable -> TypeVariable
max :: TypeVariable -> TypeVariable -> TypeVariable
$cmax :: TypeVariable -> TypeVariable -> TypeVariable
>= :: TypeVariable -> TypeVariable -> Bool
$c>= :: TypeVariable -> TypeVariable -> Bool
> :: TypeVariable -> TypeVariable -> Bool
$c> :: TypeVariable -> TypeVariable -> Bool
<= :: TypeVariable -> TypeVariable -> Bool
$c<= :: TypeVariable -> TypeVariable -> Bool
< :: TypeVariable -> TypeVariable -> Bool
$c< :: TypeVariable -> TypeVariable -> Bool
compare :: TypeVariable -> TypeVariable -> Ordering
$ccompare :: TypeVariable -> TypeVariable -> Ordering
$cp1Ord :: Eq TypeVariable
Ord)

-- | A value variable, inputted by the programmer.
newtype Variable =
  Variable Text
  deriving (Int -> Variable -> ShowS
[Variable] -> ShowS
Variable -> String
(Int -> Variable -> ShowS)
-> (Variable -> String) -> ([Variable] -> ShowS) -> Show Variable
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Variable] -> ShowS
$cshowList :: [Variable] -> ShowS
show :: Variable -> String
$cshow :: Variable -> String
showsPrec :: Int -> Variable -> ShowS
$cshowsPrec :: Int -> Variable -> ShowS
Show, Variable -> Variable -> Bool
(Variable -> Variable -> Bool)
-> (Variable -> Variable -> Bool) -> Eq Variable
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Variable -> Variable -> Bool
$c/= :: Variable -> Variable -> Bool
== :: Variable -> Variable -> Bool
$c== :: Variable -> Variable -> Bool
Eq, Eq Variable
Eq Variable
-> (Variable -> Variable -> Ordering)
-> (Variable -> Variable -> Bool)
-> (Variable -> Variable -> Bool)
-> (Variable -> Variable -> Bool)
-> (Variable -> Variable -> Bool)
-> (Variable -> Variable -> Variable)
-> (Variable -> Variable -> Variable)
-> Ord Variable
Variable -> Variable -> Bool
Variable -> Variable -> Ordering
Variable -> Variable -> Variable
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: Variable -> Variable -> Variable
$cmin :: Variable -> Variable -> Variable
max :: Variable -> Variable -> Variable
$cmax :: Variable -> Variable -> Variable
>= :: Variable -> Variable -> Bool
$c>= :: Variable -> Variable -> Bool
> :: Variable -> Variable -> Bool
$c> :: Variable -> Variable -> Bool
<= :: Variable -> Variable -> Bool
$c<= :: Variable -> Variable -> Bool
< :: Variable -> Variable -> Bool
$c< :: Variable -> Variable -> Bool
compare :: Variable -> Variable -> Ordering
$ccompare :: Variable -> Variable -> Ordering
$cp1Ord :: Eq Variable
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 (Token -> Token -> Bool
(Token -> Token -> Bool) -> (Token -> Token -> Bool) -> Eq Token
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Token -> Token -> Bool
$c/= :: Token -> Token -> Bool
== :: Token -> Token -> Bool
$c== :: Token -> Token -> Bool
Eq, Eq Token
Eq Token
-> (Token -> Token -> Ordering)
-> (Token -> Token -> Bool)
-> (Token -> Token -> Bool)
-> (Token -> Token -> Bool)
-> (Token -> Token -> Bool)
-> (Token -> Token -> Token)
-> (Token -> Token -> Token)
-> Ord Token
Token -> Token -> Bool
Token -> Token -> Ordering
Token -> Token -> Token
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: Token -> Token -> Token
$cmin :: Token -> Token -> Token
max :: Token -> Token -> Token
$cmax :: Token -> Token -> Token
>= :: Token -> Token -> Bool
$c>= :: Token -> Token -> Bool
> :: Token -> Token -> Bool
$c> :: Token -> Token -> Bool
<= :: Token -> Token -> Bool
$c<= :: Token -> Token -> Bool
< :: Token -> Token -> Bool
$c< :: Token -> Token -> Bool
compare :: Token -> Token -> Ordering
$ccompare :: Token -> Token -> Ordering
$cp1Ord :: Eq Token
Ord, Int -> Token -> ShowS
[Token] -> ShowS
Token -> String
(Int -> Token -> ShowS)
-> (Token -> String) -> ([Token] -> ShowS) -> Show Token
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Token] -> ShowS
$cshowList :: [Token] -> ShowS
show :: Token -> String
$cshow :: Token -> String
showsPrec :: Int -> Token -> ShowS
$cshowsPrec :: Int -> Token -> ShowS
Show)

data Location = Location
  { Location -> Int
locationStartLine :: !Int
  , Location -> Int
locationStartColumn :: !Int
  , Location -> Int
locationEndLine :: !Int
  , Location -> Int
locationEndColumn :: !Int
  } deriving (Int -> Location -> ShowS
[Location] -> ShowS
Location -> String
(Int -> Location -> ShowS)
-> (Location -> String) -> ([Location] -> ShowS) -> Show Location
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Location] -> ShowS
$cshowList :: [Location] -> ShowS
show :: Location -> String
$cshow :: Location -> String
showsPrec :: Int -> Location -> ShowS
$cshowsPrec :: Int -> Location -> ShowS
Show, Location -> Location -> Bool
(Location -> Location -> Bool)
-> (Location -> Location -> Bool) -> Eq Location
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Location -> Location -> Bool
$c/= :: Location -> Location -> Bool
== :: Location -> Location -> Bool
$c== :: Location -> Location -> Bool
Eq)

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