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)
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 Reference v ->
  ANormal Reference v
tracePrettyNormal :: forall v.
Var v =>
Bool -> ANormal Reference v -> ANormal Reference v
tracePrettyNormal Bool
False ANormal Reference v
tm = ANormal Reference v
tm
tracePrettyNormal Bool
True ANormal Reference v
tm = String -> ANormal Reference v -> ANormal Reference v
forall a. String -> a -> a
trace (Bool -> Int -> ANormal Reference v -> ShowS
forall v. Var v => Bool -> Int -> ANormal Reference v -> ShowS
prettyANF Bool
False Int
0 ANormal Reference v
tm String
"") ANormal Reference v
tm

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

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

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

tracePrettyGroups ::
  (Var v) =>
  Bool ->
  Map.Map Reference (SuperGroup Reference v) ->
  Map.Map Reference (SuperGroup Reference v)
tracePrettyGroups :: forall v.
Var v =>
Bool
-> Map Reference (SuperGroup Reference v)
-> Map Reference (SuperGroup Reference v)
tracePrettyGroups Bool
False Map Reference (SuperGroup Reference v)
gs = Map Reference (SuperGroup Reference v)
gs
tracePrettyGroups Bool
True Map Reference (SuperGroup Reference v)
gs =
  String
-> Map Reference (SuperGroup Reference v)
-> Map Reference (SuperGroup Reference v)
forall a. String -> a -> a
trace (Endo String -> ShowS
forall a. Endo a -> a -> a
appEndo (((Reference, SuperGroup Reference v) -> Endo String)
-> [(Reference, SuperGroup Reference 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 Reference v) -> Endo String
forall {v}.
Var v =>
(Reference, SuperGroup Reference v) -> Endo String
f (Map Reference (SuperGroup Reference v)
-> [(Reference, SuperGroup Reference v)]
forall k a. Map k a -> [(k, a)]
Map.toList Map Reference (SuperGroup Reference v)
gs)) String
"") Map Reference (SuperGroup Reference v)
gs
  where
    f :: (Reference, SuperGroup Reference v) -> Endo String
f (Reference
r, SuperGroup Reference 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 Reference v -> ShowS
forall v. Var v => String -> SuperGroup Reference v -> ShowS
prettyGroup (Reference -> String
prettyRefStr Reference
r) SuperGroup Reference 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 = Width -> Pretty ColorText -> String
toANSI Width
0 (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)] -> [(Reference, Code Reference)]
tracePrettyCodes :: Bool
-> [(Reference, Code Reference)] -> [(Reference, Code Reference)]
tracePrettyCodes Bool
False = [(Reference, Code Reference)] -> [(Reference, Code Reference)]
forall a. a -> a
id
tracePrettyCodes Bool
True = ((Reference, Code Reference) -> (Reference, Code Reference))
-> [(Reference, Code Reference)] -> [(Reference, Code Reference)]
forall a b. (a -> b) -> [a] -> [b]
map (Reference, Code Reference) -> (Reference, Code Reference)
f
  where
    f :: (Reference, Code Reference) -> (Reference, Code Reference)
f p :: (Reference, Code Reference)
p@(Reference
r, Code Reference
c) = String
-> (Reference, Code Reference) -> (Reference, Code Reference)
forall a. String -> a -> a
trace (String -> SuperGroup Reference Symbol -> ShowS
forall v. Var v => String -> SuperGroup Reference v -> ShowS
prettyGroup (Reference -> String
prettyRefStr Reference
r) (Code Reference -> SuperGroup Reference Symbol
forall ref. Code ref -> SuperGroup ref Symbol
codeGroup Code Reference
c) String
"") (Reference, Code Reference)
p