2019-10-16 18:14:48 +00:00
|
|
|
{-# LANGUAGE DuplicateRecordFields, OverloadedLists #-}
|
|
|
|
{-# OPTIONS_GHC -Wall #-}
|
|
|
|
module Data.Language.Ruby.AST
|
2019-10-17 21:28:40 +00:00
|
|
|
( Begin(..)
|
2019-10-16 18:14:48 +00:00
|
|
|
, Statement(..)
|
2019-10-17 21:28:40 +00:00
|
|
|
, Def(..)
|
2019-10-16 18:14:48 +00:00
|
|
|
, Module(..)
|
|
|
|
, Send(..)
|
2019-10-17 21:28:40 +00:00
|
|
|
, Const(..)
|
2019-10-17 18:08:25 +00:00
|
|
|
, Block(..)
|
2019-10-16 20:12:30 +00:00
|
|
|
, Casgn(..)
|
2019-10-17 21:28:40 +00:00
|
|
|
, Array(..)
|
|
|
|
, Args(..)
|
2019-10-16 20:12:30 +00:00
|
|
|
, Anything(..)
|
2019-10-17 18:08:25 +00:00
|
|
|
, Sym(..)
|
2019-10-17 21:28:40 +00:00
|
|
|
, String(..)
|
|
|
|
, Str(..)
|
|
|
|
, Lvasgn(..)
|
|
|
|
, Lvar(..)
|
|
|
|
, Ivar(..)
|
|
|
|
, Atom(..)
|
|
|
|
, Defs(..)
|
|
|
|
, Self(..)
|
|
|
|
, Nil(..)
|
|
|
|
, Cbase
|
2019-10-16 18:14:48 +00:00
|
|
|
) where
|
|
|
|
|
2019-10-17 21:28:40 +00:00
|
|
|
import Data.Aeson (parseJSON, Value(Null,Object,Number,Bool), withArray)
|
|
|
|
import Frelude hiding (String)
|
|
|
|
import qualified Frelude
|
2019-10-16 18:14:48 +00:00
|
|
|
import qualified Data.Aeson.Types as Aeson
|
|
|
|
import qualified Data.Vector as Vector
|
|
|
|
import Data.Coerce
|
|
|
|
import Data.Word
|
|
|
|
|
2019-10-17 21:28:40 +00:00
|
|
|
kebabCase :: Frelude.String -> Frelude.String
|
2019-10-16 18:14:48 +00:00
|
|
|
kebabCase = Aeson.camelTo2 '-'
|
|
|
|
|
|
|
|
aesonOptions :: Aeson.Options
|
|
|
|
aesonOptions = Aeson.defaultOptions
|
|
|
|
{ Aeson.sumEncoding = Aeson.ObjectWithSingleField
|
|
|
|
, Aeson.constructorTagModifier = kebabCase
|
|
|
|
}
|
|
|
|
|
2019-10-17 18:08:25 +00:00
|
|
|
newtype Begin = Begin [Statement]
|
2019-10-16 18:14:48 +00:00
|
|
|
|
2019-10-17 18:08:25 +00:00
|
|
|
deriving stock instance Show Begin
|
|
|
|
deriving stock instance Ord Begin
|
|
|
|
deriving stock instance Eq Begin
|
|
|
|
deriving stock instance Generic Begin
|
|
|
|
instance ToJSON Begin where
|
2019-10-16 18:14:48 +00:00
|
|
|
toEncoding = Aeson.genericToEncoding aesonOptions
|
2019-10-17 18:08:25 +00:00
|
|
|
deriving newtype instance Semigroup Begin
|
|
|
|
deriving newtype instance Monoid Begin
|
2019-10-16 18:14:48 +00:00
|
|
|
|
2019-10-17 18:08:25 +00:00
|
|
|
instance FromJSON Begin where
|
|
|
|
parseJSON = withArray "Begin" $ \as -> case Vector.toList as of
|
2019-10-17 21:28:40 +00:00
|
|
|
(Aeson.String "begin":xs) -> Begin <$> traverse parseJSON xs
|
|
|
|
_ -> Begin . pure <$> parseJSON (Aeson.Array as)
|
2019-10-16 18:14:48 +00:00
|
|
|
|
|
|
|
-- Should be 'expression'
|
|
|
|
data Statement
|
|
|
|
= StmtModule Module
|
2019-10-17 21:28:40 +00:00
|
|
|
| StmtDef Def
|
|
|
|
| StmtDefs Defs
|
2019-10-16 18:14:48 +00:00
|
|
|
| StmtSend Send
|
2019-10-17 18:08:25 +00:00
|
|
|
| StmtBlock Block
|
2019-10-17 21:28:40 +00:00
|
|
|
| StmtConst Const
|
2019-10-16 20:12:30 +00:00
|
|
|
| StmtCasgn Casgn
|
2019-10-17 21:28:40 +00:00
|
|
|
| StmtArray Array
|
2019-10-17 18:08:25 +00:00
|
|
|
| StmtSym Sym
|
2019-10-17 21:28:40 +00:00
|
|
|
| StmtStr Str
|
|
|
|
| StmtLvasgn Lvasgn
|
|
|
|
| StmtLvar Lvar
|
|
|
|
| StmtIvar Ivar
|
|
|
|
| StmtSelf Self
|
|
|
|
| StmtNil Nil
|
|
|
|
| StmtCbase Cbase
|
2019-10-16 20:12:30 +00:00
|
|
|
-- TODO Get rid of this
|
2019-10-16 18:14:48 +00:00
|
|
|
| StmtAnything Anything
|
|
|
|
|
|
|
|
deriving stock instance Show Statement
|
|
|
|
deriving stock instance Ord Statement
|
|
|
|
deriving stock instance Eq Statement
|
|
|
|
deriving stock instance Generic Statement
|
|
|
|
instance ToJSON Statement where
|
|
|
|
toEncoding = Aeson.genericToEncoding opts
|
|
|
|
where
|
|
|
|
opts = aesonOptions { Aeson.constructorTagModifier = go }
|
|
|
|
go = \case
|
|
|
|
"StmtModule" -> "module"
|
2019-10-17 21:28:40 +00:00
|
|
|
"StmtDef" -> "def"
|
|
|
|
"StmtDefs" -> "defs"
|
2019-10-16 18:14:48 +00:00
|
|
|
"StmtSend" -> "send"
|
2019-10-17 18:08:25 +00:00
|
|
|
"StmtBlock" -> "block"
|
2019-10-16 18:14:48 +00:00
|
|
|
"StmtConst" -> "const"
|
2019-10-17 18:08:25 +00:00
|
|
|
"StmtCasgn" -> "casgn"
|
|
|
|
"StmtArray" -> "array"
|
|
|
|
"StmtSym" -> "sym"
|
2019-10-17 21:28:40 +00:00
|
|
|
"StmtStr" -> "str"
|
|
|
|
"StmtLvasgn" -> "lvasgn"
|
|
|
|
"StmtLvar" -> "lvar"
|
|
|
|
"StmtIvar" -> "ivar"
|
|
|
|
"StmtSelf" -> "self"
|
|
|
|
"StmtNil" -> "nil"
|
|
|
|
"StmtCbase" -> "cbase"
|
2019-10-17 18:08:25 +00:00
|
|
|
x -> x
|
2019-10-16 18:14:48 +00:00
|
|
|
|
|
|
|
instance FromJSON Statement where
|
|
|
|
parseJSON v
|
|
|
|
= (StmtModule <$> parseJSON v)
|
2019-10-17 21:28:40 +00:00
|
|
|
<|> (StmtDef <$> parseJSON v)
|
|
|
|
<|> (StmtDefs <$> parseJSON v)
|
2019-10-16 18:14:48 +00:00
|
|
|
<|> (StmtSend <$> parseJSON v)
|
2019-10-17 21:28:40 +00:00
|
|
|
<|> (StmtBlock <$> parseJSON v)
|
2019-10-16 18:14:48 +00:00
|
|
|
<|> (StmtConst <$> parseJSON v)
|
2019-10-16 20:12:30 +00:00
|
|
|
<|> (StmtCasgn <$> parseJSON v)
|
|
|
|
<|> (StmtArray <$> parseJSON v)
|
2019-10-17 21:28:40 +00:00
|
|
|
<|> (StmtSym <$> parseJSON v)
|
|
|
|
<|> (StmtStr <$> parseJSON v)
|
|
|
|
<|> (StmtLvasgn <$> parseJSON v)
|
|
|
|
<|> (StmtLvar <$> parseJSON v)
|
|
|
|
<|> (StmtIvar <$> parseJSON v)
|
|
|
|
<|> (StmtSelf <$> parseJSON v)
|
|
|
|
<|> (StmtNil <$> parseJSON v)
|
|
|
|
<|> (StmtCbase <$> parseJSON v)
|
2019-10-16 18:14:48 +00:00
|
|
|
<|> (StmtAnything <$> parseJSON v)
|
|
|
|
|
2019-10-16 20:12:30 +00:00
|
|
|
data Casgn = Casgn
|
2019-10-17 21:28:40 +00:00
|
|
|
{ context :: Statement
|
|
|
|
, atom :: Atom
|
|
|
|
, rhs :: Statement
|
2019-10-16 20:12:30 +00:00
|
|
|
}
|
|
|
|
deriving stock instance Show Casgn
|
|
|
|
deriving stock instance Ord Casgn
|
|
|
|
deriving stock instance Eq Casgn
|
|
|
|
deriving stock instance Generic Casgn
|
|
|
|
instance ToJSON Casgn where
|
|
|
|
toEncoding = Aeson.genericToEncoding aesonOptions
|
|
|
|
instance FromJSON Casgn where
|
|
|
|
parseJSON = withArray "Module" $ \case
|
2019-10-17 21:28:40 +00:00
|
|
|
[Aeson.String "casgn", context, atom, rhs]
|
2019-10-16 20:12:30 +00:00
|
|
|
-> Casgn
|
2019-10-17 21:28:40 +00:00
|
|
|
<$> parseJSON context
|
|
|
|
<*> parseJSON atom
|
|
|
|
<*> parseJSON rhs
|
2019-10-16 20:12:30 +00:00
|
|
|
_ -> empty
|
|
|
|
|
|
|
|
|
2019-10-17 21:37:56 +00:00
|
|
|
newtype Array = Array
|
2019-10-16 20:12:30 +00:00
|
|
|
{ statements :: [Statement]
|
|
|
|
}
|
2019-10-17 21:28:40 +00:00
|
|
|
deriving stock instance Show Array
|
|
|
|
deriving stock instance Ord Array
|
|
|
|
deriving stock instance Eq Array
|
|
|
|
deriving stock instance Generic Array
|
|
|
|
instance ToJSON Array where
|
2019-10-16 20:12:30 +00:00
|
|
|
toEncoding = Aeson.genericToEncoding aesonOptions
|
2019-10-17 21:28:40 +00:00
|
|
|
instance FromJSON Array where
|
|
|
|
parseJSON = withArray "Array" $ \as -> case Vector.toList as of
|
|
|
|
Aeson.String "array":xs
|
|
|
|
-> Array
|
2019-10-16 20:12:30 +00:00
|
|
|
<$> traverse parseJSON xs
|
|
|
|
_ -> empty
|
|
|
|
|
2019-10-16 18:14:48 +00:00
|
|
|
newtype Anything = Anything Value
|
|
|
|
|
|
|
|
deriving stock instance Show Anything
|
|
|
|
instance Ord Anything where
|
|
|
|
compare = coerce compareValue
|
|
|
|
deriving stock instance Eq Anything
|
|
|
|
deriving stock instance Generic Anything
|
|
|
|
instance ToJSON Anything where
|
|
|
|
toEncoding = Aeson.genericToEncoding aesonOptions
|
|
|
|
deriving newtype instance FromJSON Anything
|
|
|
|
|
|
|
|
-- f do |x|
|
|
|
|
-- expr
|
|
|
|
-- end
|
2019-10-17 18:08:25 +00:00
|
|
|
data Block = Block
|
2019-10-16 18:14:48 +00:00
|
|
|
{ send :: Send
|
2019-10-17 21:28:40 +00:00
|
|
|
, args :: Args
|
2019-10-17 18:08:25 +00:00
|
|
|
, begin :: Begin
|
2019-10-16 18:14:48 +00:00
|
|
|
}
|
|
|
|
|
2019-10-17 18:08:25 +00:00
|
|
|
deriving stock instance Show Block
|
|
|
|
deriving stock instance Ord Block
|
|
|
|
deriving stock instance Eq Block
|
|
|
|
deriving stock instance Generic Block
|
|
|
|
instance ToJSON Block where
|
2019-10-16 18:14:48 +00:00
|
|
|
toEncoding = Aeson.genericToEncoding aesonOptions
|
2019-10-17 18:08:25 +00:00
|
|
|
instance FromJSON Block where
|
|
|
|
parseJSON = withArray "Block" $ \as -> case Vector.toList as of
|
2019-10-17 21:28:40 +00:00
|
|
|
[Aeson.String "block",send,args,begin]
|
2019-10-17 18:08:25 +00:00
|
|
|
-> Block
|
2019-10-16 18:14:48 +00:00
|
|
|
<$> parseJSON send
|
|
|
|
<*> parseJSON args
|
2019-10-17 18:08:25 +00:00
|
|
|
<*> parseJSON begin
|
2019-10-16 18:14:48 +00:00
|
|
|
_ -> empty
|
|
|
|
|
2019-10-16 20:35:15 +00:00
|
|
|
-- | It's super confusing that I've already defined a node in my AST
|
|
|
|
-- called args. This one correspond to the AST node with the label
|
|
|
|
-- "args" as reported by `ruby-parse`.
|
2019-10-17 21:28:40 +00:00
|
|
|
newtype Args = Args [Arg]
|
2019-10-16 20:35:15 +00:00
|
|
|
|
2019-10-17 21:28:40 +00:00
|
|
|
deriving stock instance Show Args
|
|
|
|
deriving stock instance Ord Args
|
|
|
|
deriving stock instance Eq Args
|
|
|
|
deriving stock instance Generic Args
|
|
|
|
instance ToJSON Args where
|
2019-10-16 20:35:15 +00:00
|
|
|
toEncoding = Aeson.genericToEncoding aesonOptions
|
2019-10-17 21:28:40 +00:00
|
|
|
instance FromJSON Args where
|
|
|
|
parseJSON = withArray "Args" $ \as -> case Vector.toList as of
|
|
|
|
(Aeson.String "args":xs) -> Args <$> traverse parseJSON xs
|
2019-10-17 18:08:25 +00:00
|
|
|
_ -> empty
|
|
|
|
|
|
|
|
data Arg = Arg Atom | KWArg Atom
|
|
|
|
|
|
|
|
deriving stock instance Show Arg
|
|
|
|
deriving stock instance Ord Arg
|
|
|
|
deriving stock instance Eq Arg
|
|
|
|
deriving stock instance Generic Arg
|
|
|
|
instance ToJSON Arg where
|
|
|
|
toEncoding = Aeson.genericToEncoding opts
|
|
|
|
where
|
|
|
|
opts = aesonOptions { Aeson.constructorTagModifier = go }
|
|
|
|
go = \case
|
|
|
|
"KWArg" -> "kwarg"
|
|
|
|
"Arg" -> "arg"
|
|
|
|
x -> x
|
|
|
|
|
|
|
|
instance FromJSON Arg where
|
|
|
|
parseJSON = withArray "Arg" $ \as -> case Vector.toList as of
|
2019-10-17 21:28:40 +00:00
|
|
|
[Aeson.String "arg" , symbol] -> Arg <$> parseJSON symbol
|
|
|
|
[Aeson.String "kwarg" , symbol] -> KWArg <$> parseJSON symbol
|
2019-10-17 18:08:25 +00:00
|
|
|
_ -> empty
|
|
|
|
|
|
|
|
newtype Atom = Atom Text
|
|
|
|
|
|
|
|
deriving stock instance Show Atom
|
|
|
|
deriving stock instance Ord Atom
|
|
|
|
deriving stock instance Eq Atom
|
|
|
|
deriving stock instance Generic Atom
|
|
|
|
instance ToJSON Atom where
|
|
|
|
toEncoding = Aeson.genericToEncoding aesonOptions
|
|
|
|
|
|
|
|
instance FromJSON Atom where
|
|
|
|
parseJSON = \case
|
2019-10-17 21:28:40 +00:00
|
|
|
Aeson.String s -> pure $ Atom s
|
2019-10-17 18:08:25 +00:00
|
|
|
_ -> empty
|
2019-10-16 20:35:15 +00:00
|
|
|
|
2019-10-17 21:28:40 +00:00
|
|
|
data Const = Const
|
|
|
|
{ context :: Statement
|
|
|
|
, atom :: Atom
|
|
|
|
}
|
2019-10-16 18:14:48 +00:00
|
|
|
|
2019-10-17 21:28:40 +00:00
|
|
|
deriving stock instance Show Const
|
|
|
|
deriving stock instance Ord Const
|
|
|
|
deriving stock instance Eq Const
|
|
|
|
deriving stock instance Generic Const
|
|
|
|
instance ToJSON Const where
|
2019-10-16 18:14:48 +00:00
|
|
|
toEncoding = Aeson.genericToEncoding aesonOptions
|
|
|
|
|
2019-10-17 21:28:40 +00:00
|
|
|
instance FromJSON Const where
|
|
|
|
parseJSON = withArray "Send" $ \case -- \ as -> case Vector.toList as of
|
|
|
|
[Aeson.String "const", context, atom] -> Const <$> parseJSON context <*> parseJSON atom
|
2019-10-16 18:14:48 +00:00
|
|
|
_ -> empty
|
|
|
|
|
|
|
|
data Send = Send
|
2019-10-17 21:28:40 +00:00
|
|
|
{ context :: Statement
|
|
|
|
, atom :: Atom
|
|
|
|
, args :: [Statement]
|
2019-10-16 18:14:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
deriving stock instance Show Send
|
|
|
|
deriving stock instance Ord Send
|
|
|
|
deriving stock instance Eq Send
|
|
|
|
deriving stock instance Generic Send
|
|
|
|
instance ToJSON Send where
|
|
|
|
toEncoding = Aeson.genericToEncoding aesonOptions
|
|
|
|
|
|
|
|
instance FromJSON Send where
|
|
|
|
parseJSON = withArray "Send" $ \ as -> case Vector.toList as of
|
2019-10-17 21:28:40 +00:00
|
|
|
(Aeson.String "send" : context : atom : args)
|
2019-10-16 18:14:48 +00:00
|
|
|
-> Send
|
2019-10-17 21:28:40 +00:00
|
|
|
<$> parseJSON context
|
|
|
|
<*> parseJSON atom
|
|
|
|
<*> parseJSON (Aeson.Array $ Vector.fromList args)
|
2019-10-16 18:14:48 +00:00
|
|
|
_ -> empty
|
|
|
|
|
|
|
|
data Module = Module
|
2019-10-17 21:28:40 +00:00
|
|
|
{ name :: Const
|
2019-10-17 18:08:25 +00:00
|
|
|
, begin :: Begin
|
2019-10-16 18:14:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
deriving stock instance Show Module
|
|
|
|
deriving stock instance Ord Module
|
|
|
|
deriving stock instance Eq Module
|
|
|
|
deriving stock instance Generic Module
|
|
|
|
instance ToJSON Module where
|
|
|
|
toEncoding = Aeson.genericToEncoding aesonOptions
|
|
|
|
|
|
|
|
instance FromJSON Module where
|
|
|
|
parseJSON = withArray "Module" $ \case
|
2019-10-17 21:28:40 +00:00
|
|
|
[Aeson.String "module", name, begin]
|
2019-10-16 18:14:48 +00:00
|
|
|
-> Module
|
|
|
|
<$> parseJSON name
|
2019-10-17 18:08:25 +00:00
|
|
|
<*> parseMaybe begin
|
2019-10-17 21:28:40 +00:00
|
|
|
[Aeson.String "class", name, _, begin]
|
2019-10-16 18:14:48 +00:00
|
|
|
-> Module
|
|
|
|
<$> parseJSON name
|
2019-10-17 18:08:25 +00:00
|
|
|
<*> parseMaybe begin
|
2019-10-16 18:14:48 +00:00
|
|
|
_ -> empty
|
|
|
|
|
|
|
|
parseMaybe :: FromJSON m => Monoid m => Value -> Aeson.Parser m
|
|
|
|
parseMaybe = \case
|
|
|
|
Null -> pure mempty
|
|
|
|
x -> parseJSON x
|
|
|
|
|
2019-10-17 21:28:40 +00:00
|
|
|
data Def = Def
|
|
|
|
{ atom :: Atom
|
|
|
|
, args :: Args
|
2019-10-17 18:08:25 +00:00
|
|
|
, begin :: Begin
|
2019-10-16 18:14:48 +00:00
|
|
|
}
|
|
|
|
|
2019-10-17 21:28:40 +00:00
|
|
|
deriving stock instance Show Def
|
|
|
|
deriving stock instance Ord Def
|
|
|
|
deriving stock instance Eq Def
|
|
|
|
deriving stock instance Generic Def
|
|
|
|
instance ToJSON Def where
|
2019-10-16 18:14:48 +00:00
|
|
|
toEncoding = Aeson.genericToEncoding aesonOptions
|
|
|
|
|
2019-10-17 21:28:40 +00:00
|
|
|
instance FromJSON Def where
|
|
|
|
parseJSON = withArray "Def" $ \case
|
|
|
|
[Aeson.String "def", name, args, begin]
|
|
|
|
-> Def
|
2019-10-16 18:14:48 +00:00
|
|
|
<$> parseJSON name
|
|
|
|
<*> parseJSON args
|
2019-10-17 18:08:25 +00:00
|
|
|
<*> parseMaybe begin
|
2019-10-16 18:14:48 +00:00
|
|
|
_ -> empty
|
|
|
|
|
2019-10-17 21:28:40 +00:00
|
|
|
-- | N.B.: 'Defs' is not meant to be the plural form of 'Def'!
|
|
|
|
data Defs = Defs
|
|
|
|
-- Is it really possible to put an arbitrary expression here? The
|
|
|
|
-- parser certainly allows it. E.g. defining
|
|
|
|
--
|
|
|
|
-- def (2+2).f
|
|
|
|
-- end
|
|
|
|
--
|
|
|
|
-- Raises the error "can't define singleton (TypeError)". We'll
|
|
|
|
-- permit it in the parser and kick the puck down the road.
|
|
|
|
{ context :: Statement
|
|
|
|
, atom :: Atom
|
|
|
|
, args :: Args
|
|
|
|
, begin :: Begin
|
|
|
|
}
|
2019-10-16 18:14:48 +00:00
|
|
|
|
2019-10-17 21:28:40 +00:00
|
|
|
deriving stock instance Show Defs
|
|
|
|
deriving stock instance Ord Defs
|
|
|
|
deriving stock instance Eq Defs
|
|
|
|
deriving stock instance Generic Defs
|
|
|
|
instance ToJSON Defs where
|
|
|
|
toEncoding = Aeson.genericToEncoding aesonOptions
|
|
|
|
|
|
|
|
instance FromJSON Defs where
|
|
|
|
parseJSON = withArray "Defs" $ \case
|
|
|
|
[Aeson.String "defs", ctxt, atom, args, begin]
|
|
|
|
-> Defs
|
|
|
|
<$> parseJSON ctxt
|
|
|
|
<*> parseJSON atom
|
|
|
|
<*> parseJSON args
|
|
|
|
<*> parseMaybe begin
|
|
|
|
_ -> empty
|
2019-10-16 18:14:48 +00:00
|
|
|
|
|
|
|
compareValue :: Aeson.Value -> Aeson.Value -> Ordering
|
|
|
|
compareValue v0 v1 = case (v0, v1) of
|
|
|
|
-- This case is buggy:
|
|
|
|
(Object o0, Object o1) -> compare (fst <$> toList o0) (fst <$> toList o1)
|
2019-10-17 21:28:40 +00:00
|
|
|
(Aeson.Array a0, Aeson.Array a1) -> foldMap (uncurry compareValue) $ zip (toList a0) (toList a1)
|
|
|
|
(Aeson.String s0, Aeson.String s1) -> compare s0 s1
|
2019-10-16 18:14:48 +00:00
|
|
|
(Number n0, Number n1) -> compare n0 n1
|
|
|
|
(Bool b0, Bool b1) -> compare b0 b1
|
|
|
|
(Null, Null) -> EQ
|
|
|
|
_ -> (compare `on` cons) v0 v1
|
|
|
|
where
|
|
|
|
-- Enumerate constructors.
|
|
|
|
cons :: Aeson.Value -> Word8
|
|
|
|
cons = \case
|
|
|
|
Object{} -> 0
|
2019-10-17 21:28:40 +00:00
|
|
|
Aeson.Array{} -> 1
|
|
|
|
Aeson.String{} -> 2
|
2019-10-16 18:14:48 +00:00
|
|
|
Number{} -> 3
|
|
|
|
Bool{} -> 4
|
|
|
|
Null{} -> 5
|
2019-10-17 18:08:25 +00:00
|
|
|
|
|
|
|
newtype Sym = Sym Atom
|
|
|
|
|
|
|
|
deriving stock instance Show Sym
|
|
|
|
deriving newtype instance Ord Sym
|
|
|
|
deriving stock instance Eq Sym
|
|
|
|
deriving stock instance Generic Sym
|
|
|
|
instance ToJSON Sym where
|
|
|
|
toEncoding = Aeson.genericToEncoding aesonOptions
|
|
|
|
instance FromJSON Sym where
|
|
|
|
parseJSON = withArray "Sym" $ \case
|
2019-10-17 21:28:40 +00:00
|
|
|
[Aeson.String "sym", atom] -> Sym <$> parseJSON atom
|
|
|
|
_ -> empty
|
|
|
|
|
|
|
|
newtype String = String Text
|
|
|
|
|
|
|
|
deriving stock instance Show String
|
|
|
|
deriving newtype instance Ord String
|
|
|
|
deriving stock instance Eq String
|
|
|
|
deriving stock instance Generic String
|
|
|
|
deriving newtype instance ToJSON String
|
|
|
|
deriving newtype instance FromJSON String
|
|
|
|
newtype Str = Str String
|
|
|
|
|
|
|
|
deriving stock instance Show Str
|
|
|
|
deriving newtype instance Ord Str
|
|
|
|
deriving stock instance Eq Str
|
|
|
|
deriving stock instance Generic Str
|
|
|
|
instance ToJSON Str where
|
|
|
|
toEncoding = Aeson.genericToEncoding aesonOptions
|
|
|
|
instance FromJSON Str where
|
|
|
|
parseJSON = withArray "Str" $ \case
|
|
|
|
[Aeson.String "str", atom] -> Str <$> parseJSON atom
|
|
|
|
_ -> empty
|
|
|
|
|
|
|
|
data Lvasgn = Lvasgn
|
|
|
|
{ atom :: Atom
|
|
|
|
, statement :: Statement
|
|
|
|
}
|
|
|
|
|
|
|
|
deriving stock instance Show Lvasgn
|
|
|
|
deriving stock instance Ord Lvasgn
|
|
|
|
deriving stock instance Eq Lvasgn
|
|
|
|
deriving stock instance Generic Lvasgn
|
|
|
|
instance ToJSON Lvasgn where
|
|
|
|
toEncoding = Aeson.genericToEncoding aesonOptions
|
|
|
|
instance FromJSON Lvasgn where
|
|
|
|
parseJSON = withArray "Lvasgn" $ \case
|
|
|
|
[Aeson.String "lvasgn", atom, statement] -> Lvasgn <$> parseJSON atom <*> parseJSON statement
|
|
|
|
_ -> empty
|
|
|
|
|
2019-10-17 21:37:56 +00:00
|
|
|
newtype Lvar = Lvar
|
2019-10-17 21:28:40 +00:00
|
|
|
{ atom :: Atom
|
|
|
|
}
|
|
|
|
|
|
|
|
deriving stock instance Show Lvar
|
|
|
|
deriving stock instance Ord Lvar
|
|
|
|
deriving stock instance Eq Lvar
|
|
|
|
deriving stock instance Generic Lvar
|
|
|
|
instance ToJSON Lvar where
|
|
|
|
toEncoding = Aeson.genericToEncoding aesonOptions
|
|
|
|
instance FromJSON Lvar where
|
|
|
|
parseJSON = withArray "Lvar" $ \case
|
|
|
|
[Aeson.String "lvar", atom] -> Lvar <$> parseJSON atom
|
|
|
|
_ -> empty
|
|
|
|
|
2019-10-17 21:37:56 +00:00
|
|
|
newtype Ivar = Ivar
|
2019-10-17 21:28:40 +00:00
|
|
|
{ atom :: Atom
|
|
|
|
}
|
|
|
|
|
|
|
|
deriving stock instance Show Ivar
|
|
|
|
deriving stock instance Ord Ivar
|
|
|
|
deriving stock instance Eq Ivar
|
|
|
|
deriving stock instance Generic Ivar
|
|
|
|
instance ToJSON Ivar where
|
|
|
|
toEncoding = Aeson.genericToEncoding aesonOptions
|
|
|
|
instance FromJSON Ivar where
|
|
|
|
parseJSON = withArray "Ivar" $ \case
|
|
|
|
[Aeson.String "ivar", atom] -> Ivar <$> parseJSON atom
|
|
|
|
_ -> empty
|
|
|
|
|
|
|
|
data Self = Self
|
|
|
|
|
|
|
|
deriving stock instance Show Self
|
|
|
|
deriving stock instance Ord Self
|
|
|
|
deriving stock instance Eq Self
|
|
|
|
deriving stock instance Generic Self
|
|
|
|
instance ToJSON Self where
|
|
|
|
toEncoding = Aeson.genericToEncoding aesonOptions
|
|
|
|
instance FromJSON Self where
|
|
|
|
parseJSON = withArray "Self" $ \case
|
|
|
|
[Aeson.String "self"] -> pure Self
|
|
|
|
_ -> empty
|
|
|
|
|
|
|
|
|
|
|
|
data Cbase = Cbase
|
|
|
|
|
|
|
|
deriving stock instance Show Cbase
|
|
|
|
deriving stock instance Ord Cbase
|
|
|
|
deriving stock instance Eq Cbase
|
|
|
|
deriving stock instance Generic Cbase
|
|
|
|
instance ToJSON Cbase where
|
|
|
|
toEncoding = Aeson.genericToEncoding aesonOptions
|
|
|
|
instance FromJSON Cbase where
|
|
|
|
parseJSON = withArray "Cbase" $ \case
|
|
|
|
[Aeson.String "cbase"] -> pure Cbase
|
|
|
|
_ -> empty
|
|
|
|
|
|
|
|
|
|
|
|
data Nil = Nil
|
|
|
|
|
|
|
|
deriving stock instance Show Nil
|
|
|
|
deriving stock instance Ord Nil
|
|
|
|
deriving stock instance Eq Nil
|
|
|
|
deriving stock instance Generic Nil
|
|
|
|
instance ToJSON Nil where
|
|
|
|
toJSON = pure Aeson.Null
|
|
|
|
instance FromJSON Nil where
|
|
|
|
parseJSON = \case
|
|
|
|
Aeson.Null -> pure Nil
|
2019-10-17 18:08:25 +00:00
|
|
|
_ -> empty
|