/- Copyright (c) 2016 Microsoft Corporation. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Author: Leonardo de Moura -/ prelude import Init.Data.String.Basic import Init.Data.UInt import Init.Data.Nat.Div import Init.Control.Id open Sum Subtype Nat universes u v class Repr (α : Type u) where repr : α → String export Repr (repr) -- This instance is needed because `id` is not reducible instance [Repr α] : Repr (id α) := inferInstanceAs (Repr α) instance : Repr Bool := ⟨fun b => cond b "true" "false"⟩ instance [Repr α] : Repr (Id α) := inferInstanceAs (Repr α) instance : Repr (Decidable p) := { repr := fun h => match h with | Decidable.isTrue _ => "true" | Decidable.isFalse _ => "false" } protected def List.reprAux [Repr α] : Bool → List α → String | b, [] => "" | true, x::xs => repr x ++ List.reprAux false xs | false, x::xs => ", " ++ repr x ++ List.reprAux false xs protected def List.repr [Repr α] : List α → String | [] => "[]" | x::xs => "[" ++ List.reprAux true (x::xs) ++ "]" instance [Repr α] : Repr (List α) := ⟨List.repr⟩ instance : Repr PUnit.{u+1} := ⟨fun u => "PUnit.unit"⟩ instance [Repr α] : Repr (ULift.{v} α) := ⟨fun v => "ULift.up (" ++ repr v.1 ++ ")"⟩ instance : Repr Unit := ⟨fun u => "()"⟩ instance [Repr α] : Repr (Option α) := ⟨fun | none => "none" | (some a) => "(some " ++ repr a ++ ")"⟩ instance [Repr α] [Repr β] : Repr (Sum α β) := ⟨fun | (inl a) => "(inl " ++ repr a ++ ")" | (inr b) => "(inr " ++ repr b ++ ")"⟩ instance [Repr α] [Repr β] : Repr (α × β) := ⟨fun ⟨a, b⟩ => "(" ++ repr a ++ ", " ++ repr b ++ ")"⟩ instance {β : α → Type v} [Repr α] [s : (x : α) → Repr (β x)] : Repr (Sigma β) := ⟨fun ⟨a, b⟩ => "⟨" ++ repr a ++ ", " ++ repr b ++ "⟩"⟩ instance {p : α → Prop} [Repr α] : Repr (Subtype p) := ⟨fun s => repr (val s)⟩ namespace Nat def digitChar (n : Nat) : Char := if n = 0 then '0' else if n = 1 then '1' else if n = 2 then '2' else if n = 3 then '3' else if n = 4 then '4' else if n = 5 then '5' else if n = 6 then '6' else if n = 7 then '7' else if n = 8 then '8' else if n = 9 then '9' else if n = 0xa then 'a' else if n = 0xb then 'b' else if n = 0xc then 'c' else if n = 0xd then 'd' else if n = 0xe then 'e' else if n = 0xf then 'f' else '*' def toDigitsCore (base : Nat) : Nat → Nat → List Char → List Char | 0, n, ds => ds | fuel+1, n, ds => let d := digitChar <| n % base; let n' := n / base; if n' = 0 then d::ds else toDigitsCore base fuel n' (d::ds) def toDigits (base : Nat) (n : Nat) : List Char := toDigitsCore base (n+1) n [] protected def repr (n : Nat) : String := (toDigits 10 n).asString def superDigitChar (n : Nat) : Char := if n = 0 then '⁰' else if n = 1 then '¹' else if n = 2 then '²' else if n = 3 then '³' else if n = 4 then '⁴' else if n = 5 then '⁵' else if n = 6 then '⁶' else if n = 7 then '⁷' else if n = 8 then '⁸' else if n = 9 then '⁹' else '*' partial def toSuperDigitsAux : Nat → List Char → List Char | n, ds => let d := superDigitChar <| n % 10; let n' := n / 10; if n' = 0 then d::ds else toSuperDigitsAux n' (d::ds) def toSuperDigits (n : Nat) : List Char := toSuperDigitsAux n [] def toSuperscriptString (n : Nat) : String := (toSuperDigits n).asString end Nat instance : Repr Nat := ⟨Nat.repr⟩ def hexDigitRepr (n : Nat) : String := String.singleton <| Nat.digitChar n def charToHex (c : Char) : String := let n := Char.toNat c; let d2 := n / 16; let d1 := n % 16; hexDigitRepr d2 ++ hexDigitRepr d1 def Char.quoteCore (c : Char) : String := if c = '\n' then "\\n" else if c = '\t' then "\\t" else if c = '\\' then "\\\\" else if c = '\"' then "\\\"" else if c.toNat <= 31 ∨ c = '\x7f' then "\\x" ++ charToHex c else String.singleton c instance : Repr Char := ⟨fun c => "'" ++ Char.quoteCore c ++ "'"⟩ def String.quote (s : String) : String := if s.isEmpty = true then "\"\"" else s.foldl (fun s c => s ++ c.quoteCore) "\"" ++ "\"" instance : Repr String := ⟨String.quote⟩ instance : Repr Substring := ⟨fun s => String.quote s.toString ++ ".toSubstring"⟩ instance : Repr String.Iterator := ⟨fun ⟨s, pos⟩ => "(String.Iterator.mk " ++ repr s ++ " " ++ repr pos ++ ")"⟩ instance (n : Nat) : Repr (Fin n) := ⟨fun f => repr (Fin.val f)⟩ instance : Repr UInt16 := ⟨fun n => repr n.toNat⟩ instance : Repr UInt32 := ⟨fun n => repr n.toNat⟩ instance : Repr UInt64 := ⟨fun n => repr n.toNat⟩ instance : Repr USize := ⟨fun n => repr n.toNat⟩ protected def Char.repr (c : Char) : String := repr c