{-|
Module      : IRTS.Portable
Description : Serialise Idris' IR to JSON.

License     : BSD3
Maintainer  : The Idris Community.
-}
{-# LANGUAGE FlexibleInstances, OverloadedStrings, TypeSynonymInstances #-}
module IRTS.Portable (writePortable) where

import Idris.Core.CaseTree
import Idris.Core.Evaluate
import Idris.Core.TT
import IRTS.Bytecode
import IRTS.CodegenCommon
import IRTS.Defunctionalise
import IRTS.Simplified

import Data.Aeson
import qualified Data.ByteString.Lazy as B
import System.IO

data CodegenFile = CGFile {
    CodegenFile -> String
fileType :: String,
    CodegenFile -> Int
version :: Int,
    CodegenFile -> CodegenInfo
cgInfo :: CodegenInfo
}

-- Update the version when the format changes
formatVersion :: Int
formatVersion :: Int
formatVersion = Int
3

writePortable :: Handle -> CodegenInfo -> IO ()
writePortable :: Handle -> CodegenInfo -> IO ()
writePortable Handle
file CodegenInfo
ci = do
    let json :: ByteString
json = CodegenFile -> ByteString
forall a. ToJSON a => a -> ByteString
encode (CodegenFile -> ByteString) -> CodegenFile -> ByteString
forall a b. (a -> b) -> a -> b
$ String -> Int -> CodegenInfo -> CodegenFile
CGFile String
"idris-codegen" Int
formatVersion CodegenInfo
ci
    Handle -> ByteString -> IO ()
B.hPut Handle
file ByteString
json

instance ToJSON CodegenFile where
    toJSON :: CodegenFile -> Value
toJSON (CGFile String
ft Int
v CodegenInfo
ci) = [Pair] -> Value
object [Text
"file-type" Text -> String -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= String
ft,
                                      Text
"version" Text -> Int -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Int
v,
                                      Text
"codegen-info" Text -> Value -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= CodegenInfo -> Value
forall a. ToJSON a => a -> Value
toJSON CodegenInfo
ci]

instance ToJSON CodegenInfo where
    toJSON :: CodegenInfo -> Value
toJSON CodegenInfo
ci = [Pair] -> Value
object [Text
"output-file" Text -> String -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= (CodegenInfo -> String
outputFile CodegenInfo
ci),
                        Text
"includes" Text -> [String] -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= (CodegenInfo -> [String]
includes CodegenInfo
ci),
                        Text
"import-dirs" Text -> [String] -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= (CodegenInfo -> [String]
importDirs CodegenInfo
ci),
                        Text
"compile-objs" Text -> [String] -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= (CodegenInfo -> [String]
compileObjs CodegenInfo
ci),
                        Text
"compile-libs" Text -> [String] -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= (CodegenInfo -> [String]
compileLibs CodegenInfo
ci),
                        Text
"compiler-flags" Text -> [String] -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= (CodegenInfo -> [String]
compilerFlags CodegenInfo
ci),
                        Text
"interfaces" Text -> Bool -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= (CodegenInfo -> Bool
interfaces CodegenInfo
ci),
                        Text
"exports" Text -> [ExportIFace] -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= (CodegenInfo -> [ExportIFace]
exportDecls CodegenInfo
ci),
                        Text
"lift-decls" Text -> [(Name, LDecl)] -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= (CodegenInfo -> [(Name, LDecl)]
liftDecls CodegenInfo
ci),
                        Text
"defun-decls" Text -> [(Name, DDecl)] -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= (CodegenInfo -> [(Name, DDecl)]
defunDecls CodegenInfo
ci),
                        Text
"simple-decls" Text -> [(Name, SDecl)] -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= (CodegenInfo -> [(Name, SDecl)]
simpleDecls CodegenInfo
ci),
                        Text
"bytecode" Text -> [(Name, [BC])] -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= (((Name, SDecl) -> (Name, [BC]))
-> [(Name, SDecl)] -> [(Name, [BC])]
forall a b. (a -> b) -> [a] -> [b]
map (Name, SDecl) -> (Name, [BC])
toBC (CodegenInfo -> [(Name, SDecl)]
simpleDecls CodegenInfo
ci)),
                        Text
"tt-decls" Text -> [(Name, TTDecl)] -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= (CodegenInfo -> [(Name, TTDecl)]
ttDecls CodegenInfo
ci)]

instance ToJSON Name where
    toJSON :: Name -> Value
toJSON Name
n = String -> Value
forall a. ToJSON a => a -> Value
toJSON (String -> Value) -> String -> Value
forall a b. (a -> b) -> a -> b
$ Name -> String
showCG Name
n

instance ToJSON ExportIFace where
    toJSON :: ExportIFace -> Value
toJSON (Export Name
n String
f [Export]
xs) = [Pair] -> Value
object [Text
"ffi-desc" Text -> Name -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Name
n,
                                     Text
"interface-file" Text -> String -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= String
f,
                                     Text
"exports" Text -> [Export] -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= [Export]
xs]

instance ToJSON FDesc where
    toJSON :: FDesc -> Value
toJSON (FCon Name
n) = [Pair] -> Value
object [Text
"FCon" Text -> Name -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Name
n]
    toJSON (FStr String
s) = [Pair] -> Value
object [Text
"FStr" Text -> String -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= String
s]
    toJSON (FDesc
FUnknown) = [Pair] -> Value
object [Text
"FUnknown" Text -> Value -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Value
Null]
    toJSON (FIO FDesc
fd) = [Pair] -> Value
object [Text
"FIO" Text -> FDesc -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= FDesc
fd]
    toJSON (FApp Name
n [FDesc]
xs) = [Pair] -> Value
object [Text
"FApp" Text -> (Name, [FDesc]) -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= (Name
n, [FDesc]
xs)]

instance ToJSON Export where
    toJSON :: Export -> Value
toJSON (ExportData FDesc
fd) = [Pair] -> Value
object [Text
"ExportData" Text -> FDesc -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= FDesc
fd]
    toJSON (ExportFun Name
n FDesc
dsc FDesc
ret [FDesc]
args) = [Pair] -> Value
object [Text
"ExportFun" Text -> (Name, FDesc, FDesc, [FDesc]) -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= (Name
n, FDesc
dsc, FDesc
ret, [FDesc]
args)]

instance ToJSON LDecl where
    toJSON :: LDecl -> Value
toJSON (LFun [LOpt]
opts Name
name [Name]
args LExp
def) = [Pair] -> Value
object [Text
"LFun" Text -> ([LOpt], Name, [Name], LExp) -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= ([LOpt]
opts, Name
name, [Name]
args, LExp
def)]
    toJSON (LConstructor Name
name Int
tag Int
ar) = [Pair] -> Value
object [Text
"LConstructor" Text -> (Name, Int, Int) -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= (Name
name, Int
tag, Int
ar)]

instance ToJSON LOpt where
    toJSON :: LOpt -> Value
toJSON LOpt
Inline = Text -> Value
String Text
"Inline"
    toJSON LOpt
NoInline = Text -> Value
String Text
"NoInline"

instance ToJSON LExp where
    toJSON :: LExp -> Value
toJSON (LV Name
lv) = [Pair] -> Value
object [Text
"LV" Text -> Name -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Name
lv]
    toJSON (LApp Bool
tail LExp
exp [LExp]
args) = [Pair] -> Value
object [Text
"LApp" Text -> (Bool, LExp, [LExp]) -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= (Bool
tail, LExp
exp, [LExp]
args)]
    toJSON (LLazyApp Name
name [LExp]
exps) = [Pair] -> Value
object [Text
"LLazyApp" Text -> (Name, [LExp]) -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= (Name
name, [LExp]
exps)]
    toJSON (LLazyExp LExp
exp) = [Pair] -> Value
object [Text
"LLazyExp" Text -> LExp -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= LExp
exp]
    toJSON (LForce LExp
exp) = [Pair] -> Value
object [Text
"LForce" Text -> LExp -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= LExp
exp]
    toJSON (LLet Name
name LExp
a LExp
b) = [Pair] -> Value
object [Text
"LLet" Text -> (Name, LExp, LExp) -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= (Name
name, LExp
a, LExp
b)]
    toJSON (LLam [Name]
args LExp
exp) = [Pair] -> Value
object [Text
"LLam" Text -> ([Name], LExp) -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= ([Name]
args, LExp
exp)]
    toJSON (LProj LExp
exp Int
i) = [Pair] -> Value
object [Text
"LProj" Text -> (LExp, Int) -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= (LExp
exp, Int
i)]
    toJSON (LCon Maybe Name
lv Int
i Name
n [LExp]
exps) = [Pair] -> Value
object [Text
"LCon" Text -> (Maybe Name, Int, Name, [LExp]) -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= (Maybe Name
lv, Int
i, Name
n, [LExp]
exps)]
    toJSON (LCase CaseType
ct LExp
exp [LAlt]
alts) = [Pair] -> Value
object [Text
"LCase" Text -> (CaseType, LExp, [LAlt]) -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= (CaseType
ct, LExp
exp, [LAlt]
alts)]
    toJSON (LConst Const
c) = [Pair] -> Value
object [Text
"LConst" Text -> Const -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Const
c]
    toJSON (LForeign FDesc
fd FDesc
ret [(FDesc, LExp)]
exps) = [Pair] -> Value
object [Text
"LForeign" Text -> (FDesc, FDesc, [(FDesc, LExp)]) -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= (FDesc
fd, FDesc
ret, [(FDesc, LExp)]
exps)]
    toJSON (LOp PrimFn
prim [LExp]
exps) = [Pair] -> Value
object [Text
"LOp" Text -> (PrimFn, [LExp]) -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= (PrimFn
prim, [LExp]
exps)]
    toJSON LExp
LNothing = [Pair] -> Value
object [Text
"LNothing" Text -> Value -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Value
Null]
    toJSON (LError String
s) = [Pair] -> Value
object [Text
"LError" Text -> String -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= String
s]

instance ToJSON LVar where
    toJSON :: LVar -> Value
toJSON (Loc Int
i) = [Pair] -> Value
object [Text
"Loc" Text -> Int -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Int
i]
    toJSON (Glob Name
n) = [Pair] -> Value
object [Text
"Glob" Text -> Name -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Name
n]

instance ToJSON CaseType where
    toJSON :: CaseType -> Value
toJSON CaseType
Updatable = Text -> Value
String Text
"Updatable"
    toJSON CaseType
Shared = Text -> Value
String Text
"Shared"

instance ToJSON LAlt where
    toJSON :: LAlt -> Value
toJSON (LConCase Int
i Name
n [Name]
ns LExp
exp) = [Pair] -> Value
object [Text
"LConCase" Text -> (Int, Name, [Name], LExp) -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= (Int
i, Name
n, [Name]
ns, LExp
exp)]
    toJSON (LConstCase Const
c LExp
exp) = [Pair] -> Value
object [Text
"LConstCase" Text -> (Const, LExp) -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= (Const
c, LExp
exp)]
    toJSON (LDefaultCase LExp
exp) = [Pair] -> Value
object [Text
"LDefaultCase" Text -> LExp -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= LExp
exp]

instance ToJSON Const where
    toJSON :: Const -> Value
toJSON (I Int
i) = [Pair] -> Value
object [Text
"int" Text -> Int -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Int
i]
    toJSON (BI Integer
i) = [Pair] -> Value
object [Text
"bigint" Text -> String -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= (Integer -> String
forall a. Show a => a -> String
show Integer
i)]
    toJSON (Fl Double
d) = [Pair] -> Value
object [Text
"double" Text -> Double -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Double
d]
    toJSON (Ch Char
c) = [Pair] -> Value
object [Text
"char" Text -> String -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= (Char -> String
forall a. Show a => a -> String
show Char
c)]
    toJSON (Str String
s) = [Pair] -> Value
object [Text
"string" Text -> String -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= String
s]
    toJSON (B8 Word8
b) = [Pair] -> Value
object [Text
"bits8" Text -> Word8 -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Word8
b]
    toJSON (B16 Word16
b) = [Pair] -> Value
object [Text
"bits16" Text -> Word16 -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Word16
b]
    toJSON (B32 Word32
b) = [Pair] -> Value
object [Text
"bits32" Text -> Word32 -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Word32
b]
    toJSON (B64 Word64
b) = [Pair] -> Value
object [Text
"bits64" Text -> Word64 -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Word64
b]
    toJSON (AType ArithTy
at) = [Pair] -> Value
object [Text
"atype" Text -> ArithTy -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= ArithTy
at]
    toJSON Const
StrType = [Pair] -> Value
object [Text
"strtype" Text -> Value -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Value
Null]
    toJSON Const
WorldType = [Pair] -> Value
object [Text
"worldtype" Text -> Value -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Value
Null]
    toJSON Const
TheWorld = [Pair] -> Value
object [Text
"theworld" Text -> Value -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Value
Null]
    toJSON Const
VoidType = [Pair] -> Value
object [Text
"voidtype" Text -> Value -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Value
Null]
    toJSON Const
Forgot = [Pair] -> Value
object [Text
"forgot" Text -> Value -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Value
Null]

instance ToJSON ArithTy where
    toJSON :: ArithTy -> Value
toJSON (ATInt IntTy
it) = [Pair] -> Value
object [Text
"ATInt" Text -> IntTy -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= IntTy
it]
    toJSON ArithTy
ATFloat = [Pair] -> Value
object [Text
"ATFloat" Text -> Value -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Value
Null]

instance ToJSON IntTy where
    toJSON :: IntTy -> Value
toJSON IntTy
it = String -> Value
forall a. ToJSON a => a -> Value
toJSON (String -> Value) -> String -> Value
forall a b. (a -> b) -> a -> b
$ IntTy -> String
intTyName IntTy
it

instance ToJSON PrimFn where
    toJSON :: PrimFn -> Value
toJSON (LPlus ArithTy
aty) = [Pair] -> Value
object [Text
"LPlus" Text -> ArithTy -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= ArithTy
aty]
    toJSON (LMinus ArithTy
aty) = [Pair] -> Value
object [Text
"LMinus" Text -> ArithTy -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= ArithTy
aty]
    toJSON (LTimes ArithTy
aty) = [Pair] -> Value
object [Text
"LTimes" Text -> ArithTy -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= ArithTy
aty]
    toJSON (LUDiv IntTy
aty) = [Pair] -> Value
object [Text
"LUDiv" Text -> IntTy -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= IntTy
aty]
    toJSON (LSDiv ArithTy
aty) = [Pair] -> Value
object [Text
"LSDiv" Text -> ArithTy -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= ArithTy
aty]
    toJSON (LURem IntTy
ity) = [Pair] -> Value
object [Text
"LURem" Text -> IntTy -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= IntTy
ity]
    toJSON (LSRem ArithTy
aty) = [Pair] -> Value
object [Text
"LSRem" Text -> ArithTy -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= ArithTy
aty]
    toJSON (LAnd IntTy
ity) = [Pair] -> Value
object [Text
"LAnd" Text -> IntTy -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= IntTy
ity]
    toJSON (LOr IntTy
ity) = [Pair] -> Value
object [Text
"LOr" Text -> IntTy -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= IntTy
ity]
    toJSON (LXOr IntTy
ity) = [Pair] -> Value
object [Text
"LXOr" Text -> IntTy -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= IntTy
ity]
    toJSON (LCompl IntTy
ity) = [Pair] -> Value
object [Text
"LCompl" Text -> IntTy -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= IntTy
ity]
    toJSON (LSHL IntTy
ity) = [Pair] -> Value
object [Text
"LSHL" Text -> IntTy -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= IntTy
ity]
    toJSON (LLSHR IntTy
ity) = [Pair] -> Value
object [Text
"LLSHR" Text -> IntTy -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= IntTy
ity]
    toJSON (LASHR IntTy
ity) = [Pair] -> Value
object [Text
"LASHR" Text -> IntTy -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= IntTy
ity]
    toJSON (LEq ArithTy
aty) = [Pair] -> Value
object [Text
"LEq" Text -> ArithTy -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= ArithTy
aty]
    toJSON (LLt IntTy
ity) = [Pair] -> Value
object [Text
"LLt" Text -> IntTy -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= IntTy
ity]
    toJSON (LLe IntTy
ity) = [Pair] -> Value
object [Text
"LLe" Text -> IntTy -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= IntTy
ity]
    toJSON (LGt IntTy
ity) = [Pair] -> Value
object [Text
"LGt" Text -> IntTy -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= IntTy
ity]
    toJSON (LGe IntTy
ity) = [Pair] -> Value
object [Text
"LGe" Text -> IntTy -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= IntTy
ity]
    toJSON (LSLt ArithTy
aty) = [Pair] -> Value
object [Text
"LSLt" Text -> ArithTy -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= ArithTy
aty]
    toJSON (LSLe ArithTy
aty) = [Pair] -> Value
object [Text
"LSLe" Text -> ArithTy -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= ArithTy
aty]
    toJSON (LSGt ArithTy
aty) = [Pair] -> Value
object [Text
"LSGt" Text -> ArithTy -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= ArithTy
aty]
    toJSON (LSGe ArithTy
aty) = [Pair] -> Value
object [Text
"LSGe" Text -> ArithTy -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= ArithTy
aty]
    toJSON (LZExt IntTy
from IntTy
to) = [Pair] -> Value
object [Text
"LZExt" Text -> (IntTy, IntTy) -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= (IntTy
from, IntTy
to)]
    toJSON (LSExt IntTy
from IntTy
to) = [Pair] -> Value
object [Text
"LSExt" Text -> (IntTy, IntTy) -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= (IntTy
from, IntTy
to)]
    toJSON (LTrunc IntTy
from IntTy
to) = [Pair] -> Value
object [Text
"LTrunc" Text -> (IntTy, IntTy) -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= (IntTy
from, IntTy
to)]
    toJSON PrimFn
LStrConcat = [Pair] -> Value
object [Text
"LStrConcat" Text -> Value -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Value
Null]
    toJSON PrimFn
LStrLt = [Pair] -> Value
object [Text
"LStrLt" Text -> Value -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Value
Null]
    toJSON PrimFn
LStrEq = [Pair] -> Value
object [Text
"LStrEq" Text -> Value -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Value
Null]
    toJSON PrimFn
LStrLen = [Pair] -> Value
object [Text
"LStrLen" Text -> Value -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Value
Null]
    toJSON (LIntFloat IntTy
ity) = [Pair] -> Value
object [Text
"LIntFloat" Text -> IntTy -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= IntTy
ity]
    toJSON (LFloatInt IntTy
ity) = [Pair] -> Value
object [Text
"LFloatInt" Text -> IntTy -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= IntTy
ity]
    toJSON (LIntStr IntTy
ity) = [Pair] -> Value
object [Text
"LIntStr" Text -> IntTy -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= IntTy
ity]
    toJSON (LStrInt IntTy
ity) = [Pair] -> Value
object [Text
"LStrInt" Text -> IntTy -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= IntTy
ity]
    toJSON (LIntCh IntTy
ity) = [Pair] -> Value
object [Text
"LIntCh" Text -> IntTy -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= IntTy
ity]
    toJSON (LChInt IntTy
ity) = [Pair] -> Value
object [Text
"LChInt" Text -> IntTy -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= IntTy
ity]
    toJSON PrimFn
LFloatStr = [Pair] -> Value
object [Text
"LFloatStr" Text -> Value -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Value
Null]
    toJSON PrimFn
LStrFloat = [Pair] -> Value
object [Text
"LStrFloat" Text -> Value -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Value
Null]
    toJSON (LBitCast ArithTy
from ArithTy
to) = [Pair] -> Value
object [Text
"LBitCast" Text -> (ArithTy, ArithTy) -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= (ArithTy
from, ArithTy
to)]
    toJSON PrimFn
LFExp = [Pair] -> Value
object [Text
"LFExp" Text -> Value -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Value
Null]
    toJSON PrimFn
LFLog = [Pair] -> Value
object [Text
"LFLog" Text -> Value -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Value
Null]
    toJSON PrimFn
LFSin = [Pair] -> Value
object [Text
"LFSin" Text -> Value -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Value
Null]
    toJSON PrimFn
LFCos = [Pair] -> Value
object [Text
"LFCos" Text -> Value -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Value
Null]
    toJSON PrimFn
LFTan = [Pair] -> Value
object [Text
"LFTan" Text -> Value -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Value
Null]
    toJSON PrimFn
LFASin = [Pair] -> Value
object [Text
"LFASin" Text -> Value -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Value
Null]
    toJSON PrimFn
LFACos = [Pair] -> Value
object [Text
"LFACos" Text -> Value -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Value
Null]
    toJSON PrimFn
LFATan = [Pair] -> Value
object [Text
"LFATan" Text -> Value -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Value
Null]
    toJSON PrimFn
LFATan2 = [Pair] -> Value
object [Text
"LFATan2" Text -> Value -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Value
Null]
    toJSON PrimFn
LFSqrt = [Pair] -> Value
object [Text
"LFSqrt" Text -> Value -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Value
Null]
    toJSON PrimFn
LFFloor = [Pair] -> Value
object [Text
"LFFloor" Text -> Value -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Value
Null]
    toJSON PrimFn
LFCeil = [Pair] -> Value
object [Text
"LFCeil" Text -> Value -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Value
Null]
    toJSON PrimFn
LFNegate = [Pair] -> Value
object [Text
"LFNegate" Text -> Value -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Value
Null]
    toJSON PrimFn
LStrHead = [Pair] -> Value
object [Text
"LStrHead" Text -> Value -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Value
Null]
    toJSON PrimFn
LStrTail = [Pair] -> Value
object [Text
"LStrTail" Text -> Value -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Value
Null]
    toJSON PrimFn
LStrCons = [Pair] -> Value
object [Text
"LStrCons" Text -> Value -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Value
Null]
    toJSON PrimFn
LStrIndex = [Pair] -> Value
object [Text
"LStrIndex" Text -> Value -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Value
Null]
    toJSON PrimFn
LStrRev = [Pair] -> Value
object [Text
"LStrRev" Text -> Value -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Value
Null]
    toJSON PrimFn
LStrSubstr = [Pair] -> Value
object [Text
"LStrSubstr" Text -> Value -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Value
Null]
    toJSON PrimFn
LReadStr = [Pair] -> Value
object [Text
"LReadStr" Text -> Value -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Value
Null]
    toJSON PrimFn
LWriteStr = [Pair] -> Value
object [Text
"LWriteStr" Text -> Value -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Value
Null]
    toJSON PrimFn
LSystemInfo = [Pair] -> Value
object [Text
"LSystemInfo" Text -> Value -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Value
Null]
    toJSON PrimFn
LFork = [Pair] -> Value
object [Text
"LFork" Text -> Value -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Value
Null]
    toJSON PrimFn
LPar = [Pair] -> Value
object [Text
"LPar" Text -> Value -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Value
Null]
    toJSON (LExternal Name
name) = [Pair] -> Value
object [Text
"LExternal" Text -> Name -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Name
name]
    toJSON PrimFn
LCrash = [Pair] -> Value
object [Text
"LCrash" Text -> Value -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Value
Null]
    toJSON PrimFn
LNoOp = [Pair] -> Value
object [Text
"LNoOp" Text -> Value -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Value
Null]

instance ToJSON DDecl where
    toJSON :: DDecl -> Value
toJSON (DFun Name
name [Name]
args DExp
exp) = [Pair] -> Value
object [Text
"DFun" Text -> (Name, [Name], DExp) -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= (Name
name, [Name]
args, DExp
exp)]
    toJSON (DConstructor Name
name Int
tag Int
arity) = [Pair] -> Value
object [Text
"DConstructor" Text -> (Name, Int, Int) -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= (Name
name, Int
tag, Int
arity)]

instance ToJSON DExp where
    toJSON :: DExp -> Value
toJSON (DV Name
lv) = [Pair] -> Value
object [Text
"DV" Text -> Name -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Name
lv]
    toJSON (DApp Bool
tail Name
name [DExp]
exps) = [Pair] -> Value
object [Text
"DApp" Text -> (Bool, Name, [DExp]) -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= (Bool
tail, Name
name, [DExp]
exps)]
    toJSON (DLet Name
name DExp
a DExp
b) = [Pair] -> Value
object [Text
"DLet" Text -> (Name, DExp, DExp) -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= (Name
name, DExp
a, DExp
b)]
    toJSON (DUpdate Name
name DExp
exp) = [Pair] -> Value
object [Text
"DUpdate" Text -> (Name, DExp) -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= (Name
name,DExp
exp)]
    toJSON (DProj DExp
exp Int
i) = [Pair] -> Value
object [Text
"DProj" Text -> (DExp, Int) -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= (DExp
exp, Int
i)]
    toJSON (DC Maybe Name
lv Int
i Name
name [DExp]
exp) = [Pair] -> Value
object [Text
"DC" Text -> (Maybe Name, Int, Name, [DExp]) -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= (Maybe Name
lv, Int
i, Name
name, [DExp]
exp)]
    toJSON (DCase CaseType
ct DExp
exp [DAlt]
alts) = [Pair] -> Value
object [Text
"DCase" Text -> (CaseType, DExp, [DAlt]) -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= (CaseType
ct, DExp
exp, [DAlt]
alts)]
    toJSON (DChkCase DExp
exp [DAlt]
alts) = [Pair] -> Value
object [Text
"DChkCase" Text -> (DExp, [DAlt]) -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= (DExp
exp, [DAlt]
alts)]
    toJSON (DConst Const
c) = [Pair] -> Value
object [Text
"DConst" Text -> Const -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Const
c]
    toJSON (DForeign FDesc
fd FDesc
ret [(FDesc, DExp)]
exps) = [Pair] -> Value
object [Text
"DForeign" Text -> (FDesc, FDesc, [(FDesc, DExp)]) -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= (FDesc
fd, FDesc
ret, [(FDesc, DExp)]
exps)]
    toJSON (DOp PrimFn
prim [DExp]
exps) = [Pair] -> Value
object [Text
"DOp" Text -> (PrimFn, [DExp]) -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= (PrimFn
prim, [DExp]
exps)]
    toJSON DExp
DNothing = [Pair] -> Value
object [Text
"DNothing" Text -> Value -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Value
Null]
    toJSON (DError String
s) = [Pair] -> Value
object [Text
"DError" Text -> String -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= String
s]

instance ToJSON DAlt where
    toJSON :: DAlt -> Value
toJSON (DConCase Int
i Name
n [Name]
ns DExp
exp) = [Pair] -> Value
object [Text
"DConCase" Text -> (Int, Name, [Name], DExp) -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= (Int
i, Name
n, [Name]
ns, DExp
exp)]
    toJSON (DConstCase Const
c DExp
exp) = [Pair] -> Value
object [Text
"DConstCase" Text -> (Const, DExp) -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= (Const
c, DExp
exp)]
    toJSON (DDefaultCase DExp
exp) = [Pair] -> Value
object [Text
"DDefaultCase" Text -> DExp -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= DExp
exp]

instance ToJSON SDecl where
    toJSON :: SDecl -> Value
toJSON (SFun Name
name [Name]
args Int
i SExp
exp) = [Pair] -> Value
object [Text
"SFun" Text -> (Name, [Name], Int, SExp) -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= (Name
name, [Name]
args, Int
i, SExp
exp)]

instance ToJSON SExp where
    toJSON :: SExp -> Value
toJSON (SV LVar
lv) = [Pair] -> Value
object [Text
"SV" Text -> LVar -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= LVar
lv]
    toJSON (SApp Bool
tail Name
name [LVar]
exps) = [Pair] -> Value
object [Text
"SApp" Text -> (Bool, Name, [LVar]) -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= (Bool
tail, Name
name, [LVar]
exps)]
    toJSON (SLet LVar
lv SExp
a SExp
b) = [Pair] -> Value
object [Text
"SLet" Text -> (LVar, SExp, SExp) -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= (LVar
lv, SExp
a, SExp
b)]
    toJSON (SUpdate LVar
lv SExp
exp) = [Pair] -> Value
object [Text
"SUpdate" Text -> (LVar, SExp) -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= (LVar
lv, SExp
exp)]
    toJSON (SProj LVar
lv Int
i) = [Pair] -> Value
object [Text
"SProj" Text -> (LVar, Int) -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= (LVar
lv, Int
i)]
    toJSON (SCon Maybe LVar
lv Int
i Name
name [LVar]
vars) = [Pair] -> Value
object [Text
"SCon" Text -> (Maybe LVar, Int, Name, [LVar]) -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= (Maybe LVar
lv, Int
i, Name
name, [LVar]
vars)]
    toJSON (SCase CaseType
ct LVar
lv [SAlt]
alts) = [Pair] -> Value
object [Text
"SCase" Text -> (CaseType, LVar, [SAlt]) -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= (CaseType
ct, LVar
lv, [SAlt]
alts)]
    toJSON (SChkCase LVar
lv [SAlt]
alts) = [Pair] -> Value
object [Text
"SChkCase" Text -> (LVar, [SAlt]) -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= (LVar
lv, [SAlt]
alts)]
    toJSON (SConst Const
c) = [Pair] -> Value
object [Text
"SConst" Text -> Const -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Const
c]
    toJSON (SForeign FDesc
fd FDesc
ret [(FDesc, LVar)]
exps) = [Pair] -> Value
object [Text
"SForeign" Text -> (FDesc, FDesc, [(FDesc, LVar)]) -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= (FDesc
fd, FDesc
ret, [(FDesc, LVar)]
exps)]
    toJSON (SOp PrimFn
prim [LVar]
vars) = [Pair] -> Value
object [Text
"SOp" Text -> (PrimFn, [LVar]) -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= (PrimFn
prim, [LVar]
vars)]
    toJSON SExp
SNothing = [Pair] -> Value
object [Text
"SNothing" Text -> Value -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Value
Null]
    toJSON (SError String
s) = [Pair] -> Value
object [Text
"SError" Text -> String -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= String
s]

instance ToJSON SAlt where
    toJSON :: SAlt -> Value
toJSON (SConCase Int
i Int
j Name
n [Name]
ns SExp
exp) = [Pair] -> Value
object [Text
"SConCase" Text -> (Int, Int, Name, [Name], SExp) -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= (Int
i, Int
j, Name
n, [Name]
ns, SExp
exp)]
    toJSON (SConstCase Const
c SExp
exp) = [Pair] -> Value
object [Text
"SConstCase" Text -> (Const, SExp) -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= (Const
c, SExp
exp)]
    toJSON (SDefaultCase SExp
exp) = [Pair] -> Value
object [Text
"SDefaultCase" Text -> SExp -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= SExp
exp]

instance ToJSON BC where
    toJSON :: BC -> Value
toJSON (ASSIGN Reg
r1 Reg
r2) = [Pair] -> Value
object [Text
"ASSIGN" Text -> (Reg, Reg) -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= (Reg
r1, Reg
r2)]
    toJSON (ASSIGNCONST Reg
r Const
c) = [Pair] -> Value
object [Text
"ASSIGNCONST" Text -> (Reg, Const) -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= (Reg
r, Const
c)]
    toJSON (UPDATE Reg
r1 Reg
r2) = [Pair] -> Value
object [Text
"UPDATE" Text -> (Reg, Reg) -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= (Reg
r1, Reg
r2)]
    toJSON (MKCON Reg
con Maybe Reg
mr Int
i [Reg]
regs) = [Pair] -> Value
object [Text
"MKCON" Text -> (Reg, Maybe Reg, Int, [Reg]) -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= (Reg
con, Maybe Reg
mr, Int
i, [Reg]
regs)]
    toJSON (CASE Bool
b Reg
r [(Int, [BC])]
alts Maybe [BC]
def) = [Pair] -> Value
object [Text
"CASE" Text -> (Bool, Reg, [(Int, [BC])], Maybe [BC]) -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= (Bool
b, Reg
r, [(Int, [BC])]
alts, Maybe [BC]
def)]
    toJSON (PROJECT Reg
r Int
loc Int
arity) = [Pair] -> Value
object [Text
"PROJECT" Text -> (Reg, Int, Int) -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= (Reg
r, Int
loc, Int
arity)]
    toJSON (PROJECTINTO Reg
r1 Reg
r2 Int
loc) = [Pair] -> Value
object [Text
"PROJECTINTO" Text -> (Reg, Reg, Int) -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= (Reg
r1, Reg
r2, Int
loc)]
    toJSON (CONSTCASE Reg
r [(Const, [BC])]
alts Maybe [BC]
def) = [Pair] -> Value
object [Text
"CONSTCASE" Text -> (Reg, [(Const, [BC])], Maybe [BC]) -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= (Reg
r, [(Const, [BC])]
alts, Maybe [BC]
def)]
    toJSON (CALL Name
name) = [Pair] -> Value
object [Text
"CALL" Text -> Name -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Name
name]
    toJSON (TAILCALL Name
name) = [Pair] -> Value
object [Text
"TAILCALL" Text -> Name -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Name
name]
    toJSON (FOREIGNCALL Reg
r FDesc
fd FDesc
ret [(FDesc, Reg)]
exps) = [Pair] -> Value
object [Text
"FOREIGNCALL" Text -> (Reg, FDesc, FDesc, [(FDesc, Reg)]) -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= (Reg
r, FDesc
fd, FDesc
ret, [(FDesc, Reg)]
exps)]
    toJSON (SLIDE Int
i) = [Pair] -> Value
object [Text
"SLIDE" Text -> Int -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Int
i]
    toJSON (RESERVE Int
i) = [Pair] -> Value
object [Text
"RESERVE" Text -> Int -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Int
i]
    toJSON (RESERVENOALLOC Int
i) = [Pair] -> Value
object [Text
"RESERVENOALLOC" Text -> Int -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Int
i]
    toJSON (ADDTOP Int
i) = [Pair] -> Value
object [Text
"ADDTOP" Text -> Int -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Int
i]
    toJSON (TOPBASE Int
i) = [Pair] -> Value
object [Text
"TOPBASE" Text -> Int -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Int
i]
    toJSON (BASETOP Int
i) = [Pair] -> Value
object [Text
"BASETOP" Text -> Int -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Int
i]
    toJSON BC
REBASE = [Pair] -> Value
object [Text
"REBASE" Text -> Value -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Value
Null]
    toJSON BC
STOREOLD = [Pair] -> Value
object [Text
"STOREOLD" Text -> Value -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Value
Null]
    toJSON (OP Reg
r PrimFn
prim [Reg]
args) = [Pair] -> Value
object [Text
"OP" Text -> (Reg, PrimFn, [Reg]) -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= (Reg
r, PrimFn
prim, [Reg]
args)]
    toJSON (NULL Reg
r) = [Pair] -> Value
object [Text
"NULL" Text -> Reg -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Reg
r]
    toJSON (ERROR String
s) = [Pair] -> Value
object [Text
"ERROR" Text -> String -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= String
s]

instance ToJSON Reg where
    toJSON :: Reg -> Value
toJSON Reg
RVal = [Pair] -> Value
object [Text
"RVal" Text -> Value -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Value
Null]
    toJSON (T Int
i) = [Pair] -> Value
object [Text
"T" Text -> Int -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Int
i]
    toJSON (L Int
i) = [Pair] -> Value
object [Text
"L" Text -> Int -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Int
i]
    toJSON Reg
Tmp = [Pair] -> Value
object [Text
"Tmp" Text -> Value -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Value
Null]

instance ToJSON RigCount where
    toJSON :: RigCount -> Value
toJSON RigCount
r = [Pair] -> Value
object [Text
"RigCount" Text -> String -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= RigCount -> String
forall a. Show a => a -> String
show RigCount
r]

instance ToJSON Totality where
    toJSON :: Totality -> Value
toJSON Totality
t = [Pair] -> Value
object [Text
"Totality" Text -> String -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Totality -> String
forall a. Show a => a -> String
show Totality
t]

instance ToJSON MetaInformation where
    toJSON :: MetaInformation -> Value
toJSON MetaInformation
m = [Pair] -> Value
object [Text
"MetaInformation" Text -> String -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= MetaInformation -> String
forall a. Show a => a -> String
show MetaInformation
m]

instance ToJSON Def where
    toJSON :: Def -> Value
toJSON (Function Type
ty Type
tm) = [Pair] -> Value
object [Text
"Function" Text -> (Type, Type) -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= (Type
ty, Type
tm)]
    toJSON (TyDecl NameType
nm Type
ty) = [Pair] -> Value
object [Text
"TyDecl" Text -> (NameType, Type) -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= (NameType
nm, Type
ty)]
    toJSON (Operator Type
ty Int
n [Value] -> Maybe Value
f) = Value
Null -- Operator and CaseOp omits same values as in IBC.hs
    toJSON (CaseOp CaseInfo
info Type
ty [(Type, Bool)]
argTy [Either Type (Type, Type)]
_ [([Name], Type, Type)]
_ CaseDefs
cdefs) = [Pair] -> Value
object [Text
"CaseOp" Text -> (CaseInfo, Type, [(Type, Bool)], CaseDefs) -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= (CaseInfo
info, Type
ty, [(Type, Bool)]
argTy, CaseDefs
cdefs)]

instance (ToJSON t) => ToJSON (TT t) where
    toJSON :: TT t -> Value
toJSON (P NameType
nt t
name TT t
term) = [Pair] -> Value
object [Text
"P" Text -> (NameType, t, TT t) -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= (NameType
nt, t
name, TT t
term)]
    toJSON (V Int
n) = [Pair] -> Value
object [Text
"V" Text -> Int -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Int
n]
    toJSON (Bind t
n Binder (TT t)
b TT t
tt) = [Pair] -> Value
object [Text
"Bind" Text -> (t, Binder (TT t), TT t) -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= (t
n, Binder (TT t)
b, TT t
tt)]
    toJSON (App AppStatus t
s TT t
t1 TT t
t2) = [Pair] -> Value
object [Text
"App" Text -> (AppStatus t, TT t, TT t) -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= (AppStatus t
s, TT t
t1, TT t
t2)]
    toJSON (Constant Const
c) = [Pair] -> Value
object [Text
"Constant" Text -> Const -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Const
c]
    toJSON (Proj TT t
tt Int
n) = [Pair] -> Value
object [Text
"Proj" Text -> (TT t, Int) -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= (TT t
tt, Int
n)]
    toJSON TT t
Erased = [Pair] -> Value
object [Text
"Erased" Text -> Value -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Value
Null]
    toJSON TT t
Impossible = [Pair] -> Value
object [Text
"Impossible" Text -> Value -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Value
Null]
    toJSON (Inferred TT t
tt) = [Pair] -> Value
object [Text
"Inferred" Text -> TT t -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= TT t
tt]
    toJSON (TType UExp
u) = [Pair] -> Value
object [Text
"TType" Text -> UExp -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= UExp
u]
    toJSON (UType Universe
u) = [Pair] -> Value
object [Text
"UType" Text -> String -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= (Universe -> String
forall a. Show a => a -> String
show Universe
u)]

instance ToJSON UExp where
    toJSON :: UExp -> Value
toJSON (UVar String
src Int
n) = [Pair] -> Value
object [Text
"UVar" Text -> (String, Int) -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= (String
src, Int
n)]
    toJSON (UVal Int
n) = [Pair] -> Value
object [Text
"UVal" Text -> Int -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Int
n]


instance (ToJSON t) => ToJSON (AppStatus t) where
    toJSON :: AppStatus t -> Value
toJSON AppStatus t
Complete = [Pair] -> Value
object [Text
"Complete" Text -> Value -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Value
Null]
    toJSON AppStatus t
MaybeHoles = [Pair] -> Value
object [Text
"MaybeHoles" Text -> Value -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Value
Null]
    toJSON (Holes [t]
ns) = [Pair] -> Value
object [Text
"Holes" Text -> [t] -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= [t]
ns]

instance (ToJSON t) => ToJSON (Binder t) where
    toJSON :: Binder t -> Value
toJSON (Lam RigCount
rc t
bty) = [Pair] -> Value
object [Text
"Lam" Text -> (RigCount, t) -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= (RigCount
rc, t
bty)]
    toJSON (Pi RigCount
c Maybe ImplicitInfo
i t
t t
k) = [Pair] -> Value
object [Text
"Pi" Text -> (RigCount, Maybe ImplicitInfo, t, t) -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= (RigCount
c, Maybe ImplicitInfo
i, t
t, t
k)]
    toJSON (Let RigCount
rc t
t t
v) = [Pair] -> Value
object [Text
"Let" Text -> (t, t) -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= (t
t, t
v)]
    toJSON (NLet t
t t
v) = [Pair] -> Value
object [Text
"NLet" Text -> (t, t) -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= (t
t, t
v)]
    toJSON (Hole t
t) = [Pair] -> Value
object [Text
"Hole" Text -> t -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= (t
t)]
    toJSON (GHole Int
l [Name]
ns t
t) = [Pair] -> Value
object [Text
"GHole" Text -> (Int, [Name], t) -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= (Int
l, [Name]
ns, t
t)]
    toJSON (Guess t
t t
v) = [Pair] -> Value
object [Text
"Guess" Text -> (t, t) -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= (t
t, t
v)]
    toJSON (PVar RigCount
rc t
t) = [Pair] -> Value
object [Text
"PVar" Text -> (RigCount, t) -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= (RigCount
rc, t
t)]
    toJSON (PVTy t
t) = [Pair] -> Value
object [Text
"PVTy" Text -> t -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= (t
t)]

instance ToJSON ImplicitInfo where
    toJSON :: ImplicitInfo -> Value
toJSON (Impl Bool
a Bool
b Bool
c) = [Pair] -> Value
object [Text
"Impl" Text -> (Bool, Bool, Bool) -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= (Bool
a, Bool
b, Bool
c)]

instance ToJSON NameType where
    toJSON :: NameType -> Value
toJSON NameType
Bound = [Pair] -> Value
object [Text
"Bound" Text -> Value -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Value
Null]
    toJSON NameType
Ref = [Pair] -> Value
object [Text
"Ref" Text -> Value -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Value
Null]
    toJSON (DCon Int
a Int
b Bool
c) = [Pair] -> Value
object [Text
"DCon" Text -> (Int, Int, Bool) -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= (Int
a, Int
b, Bool
c)]
    toJSON (TCon Int
a Int
b) = [Pair] -> Value
object [Text
"TCon" Text -> (Int, Int) -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= (Int
a, Int
b)]

instance ToJSON CaseDefs where
    toJSON :: CaseDefs -> Value
toJSON (CaseDefs ([Name], SC)
rt ([Name], SC)
ct) = [Pair] -> Value
object [Text
"Runtime" Text -> ([Name], SC) -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= ([Name], SC)
rt, Text
"Compiletime" Text -> ([Name], SC) -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= ([Name], SC)
ct]

instance (ToJSON t) => ToJSON (SC' t) where
    toJSON :: SC' t -> Value
toJSON (Case CaseType
ct Name
n [CaseAlt' t]
alts) = [Pair] -> Value
object [Text
"Case" Text -> (CaseType, Name, [CaseAlt' t]) -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= (CaseType
ct, Name
n, [CaseAlt' t]
alts)]
    toJSON (ProjCase t
t [CaseAlt' t]
alts) = [Pair] -> Value
object [Text
"ProjCase" Text -> (t, [CaseAlt' t]) -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= (t
t, [CaseAlt' t]
alts)]
    toJSON (STerm t
t) = [Pair] -> Value
object [Text
"STerm" Text -> t -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= t
t]
    toJSON (UnmatchedCase String
s) = [Pair] -> Value
object [Text
"UnmatchedCase" Text -> String -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= String
s]
    toJSON SC' t
ImpossibleCase = [Pair] -> Value
object [Text
"ImpossibleCase" Text -> Value -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Value
Null]

instance (ToJSON t) => ToJSON (CaseAlt' t) where
    toJSON :: CaseAlt' t -> Value
toJSON (ConCase Name
n Int
c [Name]
ns SC' t
sc) = [Pair] -> Value
object [Text
"ConCase" Text -> (Name, Int, [Name], SC' t) -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= (Name
n, Int
c, [Name]
ns, SC' t
sc)]
    toJSON (FnCase Name
n [Name]
ns SC' t
sc) = [Pair] -> Value
object [Text
"FnCase" Text -> (Name, [Name], SC' t) -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= (Name
n, [Name]
ns, SC' t
sc)]
    toJSON (ConstCase Const
c SC' t
sc) = [Pair] -> Value
object [Text
"ConstCase" Text -> (Const, SC' t) -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= (Const
c, SC' t
sc)]
    toJSON (SucCase Name
n SC' t
sc) = [Pair] -> Value
object [Text
"SucCase" Text -> (Name, SC' t) -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= (Name
n, SC' t
sc)]
    toJSON (DefaultCase SC' t
sc) = [Pair] -> Value
object [Text
"DefaultCase" Text -> SC' t -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.=  SC' t
sc]

instance ToJSON CaseInfo where
    toJSON :: CaseInfo -> Value
toJSON (CaseInfo Bool
a Bool
b Bool
c) = [Pair] -> Value
object [Text
"CaseInfo" Text -> (Bool, Bool, Bool) -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= (Bool
a, Bool
b, Bool
c)]

instance ToJSON Accessibility where
    toJSON :: Accessibility -> Value
toJSON Accessibility
a = [Pair] -> Value
object [Text
"Accessibility" Text -> String -> Pair
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Accessibility -> String
forall a. Show a => a -> String
show Accessibility
a]