/*---------------------------------------------------------------------------
  Copyright 2012-2024, Microsoft Research, Daan Leijen.

  This is free software; you can redistribute it and/or modify it under the
  terms of the Apache License, Version 2.0. A copy of the License can be
  found in the LICENSE file at the root of this distribution.
---------------------------------------------------------------------------*/

// Standard show functions.
module std/core/showstd/core/show

import std/core/typesstd/core/types
import std/core/hndstd/core/hnd
import std/core/intstd/core/int
import std/core/charstd/core/char
import std/core/stringstd/core/string
import std/core/sslicestd/core/sslice
import std/core/liststd/core/list


// ----------------------------------------------------------------------------
// Show
// ----------------------------------------------------------------------------

// Generic show: shows the internal representation of an object as a string
// Note: this breaks parametricity so it should not be public
extern gshowstd/core/show/gshow: forall<a> (a) -> string : forall<aa: V> aa: V -> stringstd/core/types/string: V
  c "kk_show_any"
  cs inline "#1.ToString()"
  js inline "#1.toString()"

extern int-show-hexstd/core/show/int-show-hex: (i : int, use-capitals : bool) -> string(ii: int:intstd/core/types/int: V,use-capitalsuse-capitals: bool:boolstd/core/types/bool: V) : stringstd/core/types/string: V
  c "kk_integer_to_hex_string"
  cs "Primitive.IntShowHex"
  js "$std_core_types._int_showhex"

// Show an `:int` as a hexadecimal value.\
// The `width`  parameter specifies how wide the hex value is where `"0"`  is used to align.\
// The `use-capitals` parameter (= `True`) determines if captical letters should be used to display the hexadecimal digits.\
// The `pre` (=`"0x"`) is an optional prefix for the number (goes between the sign and the number).
pub fun show-hexstd/core/show/show-hex: (i : int, width : ? int, use-capitals : ? bool, pre : ? string) -> string( ii: int : intstd/core/types/int: V, widthwidth: ? int : intstd/core/types/int: V = 1literal: int
dec = 1
hex8 = 0x01
bit8 = 0b00000001
, use-capitalsuse-capitals: ? bool : boolstd/core/types/bool: V = Truestd/core/types/True: bool, prepre: ? string : stringstd/core/types/string: V = "0x"literal: string
count= 2
)result: -> total string (if ii: int <std/core/int/(<): (x : int, y : int) -> bool 0literal: int
dec = 0
hex8 = 0x00
bit8 = 0b00000000
then "-"literal: string
count= 1
else ""literal: string
count= 0
) ++std/core/types/(++): (x : string, y : string) -> string prepre: string ++std/core/types/(++): (x : string, y : string) -> string int-show-hexstd/core/show/int-show-hex: (i : int, use-capitals : bool) -> string(ii: int.absstd/core/int/abs: (i : int) -> int,use-capitalsuse-capitals: bool).pad-leftstd/core/string/pad-left: (s : string, width : int, fill : ? char) -> string(widthwidth: int,'0'literal: char
unicode= u0030
) // Show a character as a string pub fun show-charstd/core/show/show-char: (c : char) -> string( cc: char : charstd/core/types/char: V )result: -> total string : stringstd/core/types/string: V if cc: char <std/core/char/(<): (char, char) -> bool ' 'literal: char
unicode= u0020
||std/core/types/(||): (x : bool, y : bool) -> bool cc: char >std/core/char/(>): (char, char) -> bool '~'literal: char
unicode= u007E
then if cc: char ==std/core/char/(==): (char, char) -> bool '\n'literal: char
unicode= u000A
then "\\n"literal: string
count= 2
elif cc: char ==std/core/char/(==): (char, char) -> bool '\r'literal: char
unicode= u000D
then "\\r"literal: string
count= 2
elif cc: char ==std/core/char/(==): (char, char) -> bool '\t'literal: char
unicode= u0009
then "\\t"literal: string
count= 2
elif cc: char.intstd/core/char/int: (char) -> int <=std/core/int/(<=): (x : int, y : int) -> bool 0xFFliteral: int
dec = 255
hex16= 0x00FF
bit16= 0b0000000011111111
then "\\x"literal: string
count= 2
++std/core/types/(++): (x : string, y : string) -> string cc: char.intstd/core/char/int: (char) -> int.show-hexstd/core/show/show-hex: (i : int, width : ? int, use-capitals : ? bool, pre : ? string) -> string(2literal: int
dec = 2
hex8 = 0x02
bit8 = 0b00000010
,pre=""literal: string
count= 0
) elif cc: char.intstd/core/char/int: (char) -> int <=std/core/int/(<=): (x : int, y : int) -> bool 0xFFFFliteral: int
dec = 65535
hex32= 0x0000FFFF
bit32= 0b00000000000000001111111111111111
then "\\u"literal: string
count= 2
++std/core/types/(++): (x : string, y : string) -> string cc: char.intstd/core/char/int: (char) -> int.show-hexstd/core/show/show-hex: (i : int, width : ? int, use-capitals : ? bool, pre : ? string) -> string(4literal: int
dec = 4
hex8 = 0x04
bit8 = 0b00000100
,pre=""literal: string
count= 0
) else "\\U"literal: string
count= 2
++std/core/types/(++): (x : string, y : string) -> string cc: char.intstd/core/char/int: (char) -> int.show-hexstd/core/show/show-hex: (i : int, width : ? int, use-capitals : ? bool, pre : ? string) -> string(6literal: int
dec = 6
hex8 = 0x06
bit8 = 0b00000110
,pre=""literal: string
count= 0
) else if cc: char ==std/core/char/(==): (char, char) -> bool '\''literal: char
unicode= u0027
then "\\'"literal: string
count= 2
elif cc: char ==std/core/char/(==): (char, char) -> bool '"'literal: char
unicode= u0022
then "\\\""literal: string
count= 2
elif cc: char ==std/core/char/(==): (char, char) -> bool '\\'literal: char
unicode= u005C
then "\\\\"literal: string
count= 2
else cc: char.stringstd/core/string/char/string: (c : char) -> string
// Show a `:char` as a character literal pub fun char/showstd/core/show/char/show: (c : char) -> string( cc: char : charstd/core/types/char: V )result: -> total string : stringstd/core/types/string: V "'"literal: string
count= 1
++std/core/types/(++): (x : string, y : string) -> string cc: char.show-charstd/core/show/show-char: (c : char) -> string ++std/core/types/(++): (x : string, y : string) -> string "'"literal: string
count= 1
// Show a string as a string literal pub noinline fun string/showstd/core/show/string/show: (s : string) -> string( ss: string : stringstd/core/types/string: V )result: -> total string : stringstd/core/types/string: V "\""literal: string
count= 1
++std/core/types/(++): (x : string, y : string) -> string ss: string.liststd/core/string/list: (s : string) -> list<char>.mapstd/core/list/map: (xs : list<char>, f : (char) -> string) -> list<string>(show-charstd/core/show/show-char: (c : char) -> string).joinstd/core/list/join: (xs : list<string>) -> string ++std/core/types/(++): (x : string, y : string) -> string "\""literal: string
count= 1
// Show an `:sslice` as a string literal pub fun sslice/showstd/core/show/sslice/show: (s : sslice) -> string( ss: sslice : sslicestd/core/sslice/sslice: V )result: -> total string : stringstd/core/types/string: V ss: sslice.stringstd/core/sslice/string: (slice : sslice) -> string.showstd/core/show/string/show: (s : string) -> string