module Unison.Runtime.Debug
  ( traceComb,
    traceCombs,
    tracePretty,
    tracePrettyDefs,
    tracePrettyCodes,
    tracePrettyGroup,
    tracePrettyRGroup,
    tracePrettyRPGroup,
    tracePrettyGroups,
    tracePrettyNormal,
    module Debug.Trace,
  )
where

import Data.Map qualified as Map
import Data.Monoid (Endo (..))
import Data.Word
import Debug.Trace
import Unison.PrettyPrintEnv (PrettyPrintEnv)
import Unison.Reference (Reference, toShortHash)
import Unison.Runtime.ANF
import Unison.Runtime.MCode
import Unison.ShortHash (shortenTo)
import Unison.Syntax.NamePrinter (prettyShortHash)
import Unison.Syntax.TermPrinter (pretty)
import Unison.Term qualified as Tm
import Unison.Util.EnumContainers
import Unison.Util.Pretty (ColorText, Pretty, toANSI, toAnsiUnbroken)
import Unison.Var (Var)

type Term v = Tm.Term v ()

traceComb :: (Show clos, Show comb) => Bool -> Word64 -> GComb clos comb -> Bool
traceComb :: forall clos comb.
(Show clos, Show comb) =>
Bool -> Word64 -> GComb clos comb -> Bool
traceComb Bool
False Word64
_ GComb clos comb
_ = Bool
True
traceComb Bool
True Word64
w GComb clos comb
c = String -> Bool -> Bool
forall a. String -> a -> a
trace (Word64 -> Word64 -> GComb clos comb -> ShowS
forall val comb.
(Show val, Show comb) =>
Word64 -> Word64 -> GComb val comb -> ShowS
prettyComb Word64
w Word64
0 GComb clos comb
c String
"\n") Bool
True

traceCombs ::
  Word64 ->
  Bool ->
  EnumMap Word64 Comb ->
  EnumMap Word64 Comb
traceCombs :: Word64 -> Bool -> EnumMap Word64 Comb -> EnumMap Word64 Comb
traceCombs Word64
_ Bool
False EnumMap Word64 Comb
c = EnumMap Word64 Comb
c
traceCombs Word64
w Bool
True EnumMap Word64 Comb
c = String -> EnumMap Word64 Comb -> EnumMap Word64 Comb
forall a. String -> a -> a
trace (Word64 -> EnumMap Word64 Comb -> ShowS
prettyCombs Word64
w EnumMap Word64 Comb
c String
"") EnumMap Word64 Comb
c

tracePretty ::
  (Var v) =>
  PrettyPrintEnv ->
  Bool ->
  Term v ->
  Term v
tracePretty :: forall v. Var v => PrettyPrintEnv -> Bool -> Term v -> Term v
tracePretty PrettyPrintEnv
_ Bool
False Term v
tm = Term v
tm
tracePretty PrettyPrintEnv
ppe Bool
True Term v
tm = String -> Term v -> Term v
forall a. String -> a -> a
trace (Width -> Pretty ColorText -> String
toANSI Width
50 (Pretty ColorText -> String) -> Pretty ColorText -> String
forall a b. (a -> b) -> a -> b
$ PrettyPrintEnv -> Term v -> Pretty ColorText
forall v a.
(HasCallStack, Var v) =>
PrettyPrintEnv -> Term v a -> Pretty ColorText
pretty PrettyPrintEnv
ppe Term v
tm) Term v
tm

tracePrettyDefs ::
  (Var v) =>
  PrettyPrintEnv ->
  Bool ->
  [(Reference, Term v)] ->
  [(Reference, Term v)]
tracePrettyDefs :: forall v.
Var v =>
PrettyPrintEnv
-> Bool -> [(Reference, Term v)] -> [(Reference, Term v)]
tracePrettyDefs PrettyPrintEnv
_ Bool
False [(Reference, Term v)]
tms = [(Reference, Term v)]
tms
tracePrettyDefs PrettyPrintEnv
ppe Bool
True [(Reference, Term v)]
tms = ((Reference, Term v) -> (Reference, Term v))
-> [(Reference, Term v)] -> [(Reference, Term v)]
forall a b. (a -> b) -> [a] -> [b]
map (Reference, Term v) -> (Reference, Term v)
f [(Reference, Term v)]
tms
  where
    f :: (Reference, Term v) -> (Reference, Term v)
f p :: (Reference, Term v)
p@(Reference
r, Term v
tm) =
      String -> (Reference, Term v) -> (Reference, Term v)
forall a. String -> a -> a
trace (Width -> Pretty ColorText -> String
toANSI Width
50 (Pretty ColorText -> String) -> Pretty ColorText -> String
forall a b. (a -> b) -> a -> b
$ Reference -> Pretty ColorText
prettyRef Reference
r Pretty ColorText -> Pretty ColorText -> Pretty ColorText
forall a. Semigroup a => a -> a -> a
<> Pretty ColorText
" := " Pretty ColorText -> Pretty ColorText -> Pretty ColorText
forall a. Semigroup a => a -> a -> a
<> PrettyPrintEnv -> Term v -> Pretty ColorText
forall v a.
(HasCallStack, Var v) =>
PrettyPrintEnv -> Term v a -> Pretty ColorText
pretty PrettyPrintEnv
ppe Term v
tm) (Reference, Term v)
p

tracePrettyNormal ::
  (Var v) =>
  Bool ->
  ANormal v ->
  ANormal v
tracePrettyNormal :: forall v. Var v => Bool -> ANormal v -> ANormal v
tracePrettyNormal Bool
False ANormal v
tm = ANormal v
tm
tracePrettyNormal Bool
True ANormal v
tm = String -> ANormal v -> ANormal v
forall a. String -> a -> a
trace (Bool -> Int -> ANormal v -> ShowS
forall v. Var v => Bool -> Int -> ANormal v -> ShowS
prettyANF Bool
False Int
0 ANormal v
tm String
"") ANormal v
tm

tracePrettyGroup ::
  (Var v) =>
  String ->
  Bool ->
  SuperGroup v ->
  SuperGroup v
tracePrettyGroup :: forall v. Var v => String -> Bool -> SuperGroup v -> SuperGroup v
tracePrettyGroup String
_ Bool
False SuperGroup v
g = SuperGroup v
g
tracePrettyGroup String
w Bool
True SuperGroup v
g = String -> SuperGroup v -> SuperGroup v
forall a. String -> a -> a
trace (String -> SuperGroup v -> ShowS
forall v. Var v => String -> SuperGroup v -> ShowS
prettyGroup String
w SuperGroup v
g String
"") SuperGroup v
g

tracePrettyRGroup ::
  (Var v) =>
  Reference ->
  Bool ->
  SuperGroup v ->
  SuperGroup v
tracePrettyRGroup :: forall v.
Var v =>
Reference -> Bool -> SuperGroup v -> SuperGroup v
tracePrettyRGroup = String -> Bool -> SuperGroup v -> SuperGroup v
forall v. Var v => String -> Bool -> SuperGroup v -> SuperGroup v
tracePrettyGroup (String -> Bool -> SuperGroup v -> SuperGroup v)
-> (Reference -> String)
-> Reference
-> Bool
-> SuperGroup v
-> SuperGroup v
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Reference -> String
prettyRefStr

tracePrettyRPGroup ::
  (Var v) =>
  Reference ->
  (SuperGroup v -> Bool) ->
  SuperGroup v ->
  SuperGroup v
tracePrettyRPGroup :: forall v.
Var v =>
Reference -> (SuperGroup v -> Bool) -> SuperGroup v -> SuperGroup v
tracePrettyRPGroup Reference
r SuperGroup v -> Bool
p SuperGroup v
g = Reference -> Bool -> SuperGroup v -> SuperGroup v
forall v.
Var v =>
Reference -> Bool -> SuperGroup v -> SuperGroup v
tracePrettyRGroup Reference
r (SuperGroup v -> Bool
p SuperGroup v
g) SuperGroup v
g

tracePrettyGroups ::
  (Var v) =>
  Bool ->
  Map.Map Reference (SuperGroup v) ->
  Map.Map Reference (SuperGroup v)
tracePrettyGroups :: forall v.
Var v =>
Bool
-> Map Reference (SuperGroup v) -> Map Reference (SuperGroup v)
tracePrettyGroups Bool
False Map Reference (SuperGroup v)
gs = Map Reference (SuperGroup v)
gs
tracePrettyGroups Bool
True Map Reference (SuperGroup v)
gs =
  String
-> Map Reference (SuperGroup v) -> Map Reference (SuperGroup v)
forall a. String -> a -> a
trace (Endo String -> ShowS
forall a. Endo a -> a -> a
appEndo (((Reference, SuperGroup v) -> Endo String)
-> [(Reference, SuperGroup v)] -> Endo String
forall m a. Monoid m => (a -> m) -> [a] -> m
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap (Reference, SuperGroup v) -> Endo String
forall {v}. Var v => (Reference, SuperGroup v) -> Endo String
f (Map Reference (SuperGroup v) -> [(Reference, SuperGroup v)]
forall k a. Map k a -> [(k, a)]
Map.toList Map Reference (SuperGroup v)
gs)) String
"") Map Reference (SuperGroup v)
gs
  where
    f :: (Reference, SuperGroup v) -> Endo String
f (Reference
r, SuperGroup v
g) = ShowS -> Endo String
forall a. (a -> a) -> Endo a
Endo (ShowS -> Endo String) -> ShowS -> Endo String
forall a b. (a -> b) -> a -> b
$ String -> SuperGroup v -> ShowS
forall v. Var v => String -> SuperGroup v -> ShowS
prettyGroup (Reference -> String
prettyRefStr Reference
r) SuperGroup v
g ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> ShowS
showString String
"\n\n"

prettyRef :: Reference -> Pretty ColorText
prettyRef :: Reference -> Pretty ColorText
prettyRef = ShortHash -> Pretty ColorText
forall s. IsString s => ShortHash -> Pretty s
prettyShortHash (ShortHash -> Pretty ColorText)
-> (Reference -> ShortHash) -> Reference -> Pretty ColorText
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> ShortHash -> ShortHash
shortenTo Int
10 (ShortHash -> ShortHash)
-> (Reference -> ShortHash) -> Reference -> ShortHash
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Reference -> ShortHash
toShortHash

prettyRefStr :: Reference -> String
prettyRefStr :: Reference -> String
prettyRefStr = Pretty ColorText -> String
toAnsiUnbroken (Pretty ColorText -> String)
-> (Reference -> Pretty ColorText) -> Reference -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Reference -> Pretty ColorText
prettyRef

tracePrettyCodes :: Bool -> [(Reference, Code)] -> [(Reference, Code)]
tracePrettyCodes :: Bool -> [(Reference, Code)] -> [(Reference, Code)]
tracePrettyCodes Bool
False = [(Reference, Code)] -> [(Reference, Code)]
forall a. a -> a
id
tracePrettyCodes Bool
True = ((Reference, Code) -> (Reference, Code))
-> [(Reference, Code)] -> [(Reference, Code)]
forall a b. (a -> b) -> [a] -> [b]
map (Reference, Code) -> (Reference, Code)
f
  where
    f :: (Reference, Code) -> (Reference, Code)
f p :: (Reference, Code)
p@(Reference
r, Code
c) = String -> (Reference, Code) -> (Reference, Code)
forall a. String -> a -> a
trace (String -> SuperGroup Symbol -> ShowS
forall v. Var v => String -> SuperGroup v -> ShowS
prettyGroup (Reference -> String
prettyRefStr Reference
r) (Code -> SuperGroup Symbol
codeGroup Code
c) String
"") (Reference, Code)
p