| /- | |
| Copyright (c) 2020 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.Data.Repr | |
| import Init.Data.Int.Basic | |
| import Init.Data.Format.Basic | |
| import Init.Control.Id | |
| import Init.Control.Option | |
| open Sum Subtype Nat | |
| open Std | |
| class ToString (α : Type u) where | |
| toString : α → String | |
| export ToString (toString) | |
| -- This instance is needed because `id` is not reducible | |
| instance {α} [ToString α] : ToString (id α) := | |
| inferInstanceAs (ToString α) | |
| instance {α} [ToString α] : ToString (Id α) := | |
| inferInstanceAs (ToString α) | |
| instance : ToString String := | |
| ⟨fun s => s⟩ | |
| instance : ToString Substring := | |
| ⟨fun s => s.toString⟩ | |
| instance : ToString String.Iterator := | |
| ⟨fun it => it.remainingToString⟩ | |
| instance : ToString Bool := | |
| ⟨fun b => cond b "true" "false"⟩ | |
| instance {p : Prop} : ToString (Decidable p) := ⟨fun h => | |
| match h with | |
| | Decidable.isTrue _ => "true" | |
| | Decidable.isFalse _ => "false"⟩ | |
| protected def List.toStringAux {α : Type u} [ToString α] : Bool → List α → String | |
| | b, [] => "" | |
| | true, x::xs => toString x ++ List.toStringAux false xs | |
| | false, x::xs => ", " ++ toString x ++ List.toStringAux false xs | |
| protected def List.toString {α : Type u} [ToString α] : List α → String | |
| | [] => "[]" | |
| | x::xs => "[" ++ List.toStringAux true (x::xs) ++ "]" | |
| instance {α : Type u} [ToString α] : ToString (List α) := | |
| ⟨List.toString⟩ | |
| instance : ToString PUnit.{u+1} := | |
| ⟨fun _ => "()"⟩ | |
| instance {α : Type u} [ToString α] : ToString (ULift.{v} α) := | |
| ⟨fun v => toString v.1⟩ | |
| instance : ToString Unit := | |
| ⟨fun u => "()"⟩ | |
| instance : ToString Nat := | |
| ⟨fun n => Nat.repr n⟩ | |
| instance : ToString Int where | |
| toString | |
| | Int.ofNat m => toString m | |
| | Int.negSucc m => "-" ++ toString (succ m) | |
| instance : ToString Char := | |
| ⟨fun c => c.toString⟩ | |
| instance (n : Nat) : ToString (Fin n) := | |
| ⟨fun f => toString (Fin.val f)⟩ | |
| instance : ToString UInt8 := | |
| ⟨fun n => toString n.toNat⟩ | |
| instance : ToString UInt16 := | |
| ⟨fun n => toString n.toNat⟩ | |
| instance : ToString UInt32 := | |
| ⟨fun n => toString n.toNat⟩ | |
| instance : ToString UInt64 := | |
| ⟨fun n => toString n.toNat⟩ | |
| instance : ToString USize := | |
| ⟨fun n => toString n.toNat⟩ | |
| instance : ToString Format where | |
| toString f := f.pretty | |
| def addParenHeuristic (s : String) : String := | |
| if "(".isPrefixOf s || "[".isPrefixOf s || "{".isPrefixOf s || "#[".isPrefixOf s then s | |
| else if !s.any Char.isWhitespace then s | |
| else "(" ++ s ++ ")" | |
| instance {α : Type u} [ToString α] : ToString (Option α) := ⟨fun | |
| | none => "none" | |
| | (some a) => "(some " ++ addParenHeuristic (toString a) ++ ")"⟩ | |
| instance {α : Type u} {β : Type v} [ToString α] [ToString β] : ToString (Sum α β) := ⟨fun | |
| | (inl a) => "(inl " ++ addParenHeuristic (toString a) ++ ")" | |
| | (inr b) => "(inr " ++ addParenHeuristic (toString b) ++ ")"⟩ | |
| instance {α : Type u} {β : Type v} [ToString α] [ToString β] : ToString (α × β) := ⟨fun (a, b) => | |
| "(" ++ toString a ++ ", " ++ toString b ++ ")"⟩ | |
| instance {α : Type u} {β : α → Type v} [ToString α] [s : ∀ x, ToString (β x)] : ToString (Sigma β) := ⟨fun ⟨a, b⟩ => | |
| "⟨" ++ toString a ++ ", " ++ toString b ++ "⟩"⟩ | |
| instance {α : Type u} {p : α → Prop} [ToString α] : ToString (Subtype p) := ⟨fun s => | |
| toString (val s)⟩ | |
| def String.toInt? (s : String) : Option Int := | |
| OptionM.run do | |
| if s.get 0 = '-' then do | |
| let v ← (s.toSubstring.drop 1).toNat?; | |
| pure <| - Int.ofNat v | |
| else | |
| Int.ofNat <$> s.toNat? | |
| def String.isInt (s : String) : Bool := | |
| if s.get 0 = '-' then | |
| (s.toSubstring.drop 1).isNat | |
| else | |
| s.isNat | |
| def String.toInt! (s : String) : Int := | |
| match s.toInt? with | |
| | some v => v | |
| | none => panic "Int expected" | |
| instance [ToString ε] [ToString α] : ToString (Except ε α) where | |
| toString | |
| | Except.error e => "error: " ++ toString e | |
| | Except.ok a => "ok: " ++ toString a | |
| instance [Repr ε] [Repr α] : Repr (Except ε α) where | |
| reprPrec | |
| | Except.error e, prec => Repr.addAppParen ("Except.error " ++ reprArg e) prec | |
| | Except.ok a, prec => Repr.addAppParen ("Except.ok " ++ reprArg a) prec |