module SyntaxTrees.Json (JsExpression(..)) where

import Utils.Foldable (stringify)
import Utils.Map (showMap)

import Data.Map (Map)
import Data.Char (toLower)



data JsExpression = JsNumber Double | JsBool Bool |
                    JsString String |
                    JsArray [JsExpression] |
                    JsObject (Map String JsExpression) |
                    JsNull deriving (JsExpression -> JsExpression -> Bool
(JsExpression -> JsExpression -> Bool)
-> (JsExpression -> JsExpression -> Bool) -> Eq JsExpression
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: JsExpression -> JsExpression -> Bool
$c/= :: JsExpression -> JsExpression -> Bool
== :: JsExpression -> JsExpression -> Bool
$c== :: JsExpression -> JsExpression -> Bool
Eq, Eq JsExpression
Eq JsExpression
-> (JsExpression -> JsExpression -> Ordering)
-> (JsExpression -> JsExpression -> Bool)
-> (JsExpression -> JsExpression -> Bool)
-> (JsExpression -> JsExpression -> Bool)
-> (JsExpression -> JsExpression -> Bool)
-> (JsExpression -> JsExpression -> JsExpression)
-> (JsExpression -> JsExpression -> JsExpression)
-> Ord JsExpression
JsExpression -> JsExpression -> Bool
JsExpression -> JsExpression -> Ordering
JsExpression -> JsExpression -> JsExpression
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 :: JsExpression -> JsExpression -> JsExpression
$cmin :: JsExpression -> JsExpression -> JsExpression
max :: JsExpression -> JsExpression -> JsExpression
$cmax :: JsExpression -> JsExpression -> JsExpression
>= :: JsExpression -> JsExpression -> Bool
$c>= :: JsExpression -> JsExpression -> Bool
> :: JsExpression -> JsExpression -> Bool
$c> :: JsExpression -> JsExpression -> Bool
<= :: JsExpression -> JsExpression -> Bool
$c<= :: JsExpression -> JsExpression -> Bool
< :: JsExpression -> JsExpression -> Bool
$c< :: JsExpression -> JsExpression -> Bool
compare :: JsExpression -> JsExpression -> Ordering
$ccompare :: JsExpression -> JsExpression -> Ordering
$cp1Ord :: Eq JsExpression
Ord)


instance Show JsExpression where
  show :: JsExpression -> String
show = \case
    JsExpression
JsNull       -> String
"null"
    JsNumber Double
n   -> Double -> String
forall a. Show a => a -> String
show Double
n
    JsBool Bool
bool  -> Char -> Char
toLower (Char -> Char) -> ShowS
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Bool -> String
forall a. Show a => a -> String
show Bool
bool
    JsString String
str -> ShowS
forall a. Show a => a -> String
show String
str
    JsArray [JsExpression]
arr  -> String -> String -> String -> Int -> [String] -> String
forall (m :: * -> *).
Foldable m =>
String -> String -> String -> Int -> m String -> String
stringify String
",\n" String
"[\n" String
"\n]" Int
2 ([String] -> String) -> [String] -> String
forall a b. (a -> b) -> a -> b
$ JsExpression -> String
forall a. Show a => a -> String
show   (JsExpression -> String) -> [JsExpression] -> [String]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [JsExpression]
arr
    JsObject Map String JsExpression
obj -> String -> String -> String -> Int -> [String] -> String
forall (m :: * -> *).
Foldable m =>
String -> String -> String -> Int -> m String -> String
stringify String
",\n" String
"{\n" String
"\n}" Int
2 ([String] -> String) -> [String] -> String
forall a b. (a -> b) -> a -> b
$ String
-> ShowS
-> (JsExpression -> String)
-> Map String JsExpression
-> [String]
forall a.
String -> ShowS -> (a -> String) -> Map String a -> [String]
showMap String
": " ShowS
forall a. a -> a
id JsExpression -> String
forall a. Show a => a -> String
show Map String JsExpression
obj