lean4-htt/library/init/lean/position.lean
Leonardo de Moura 60f8d17942 refactor(library/init/data/string/basic): simplify String.Iterator
The `offset` field is problematic because it prevents us from having an
efficient way of moving back and forth between `String.Pos` and `String.Iterator`.

@kha I temporarily added `String.OldIterator` for making sure the
parser doesn't break. This is a temporary fix that will be eliminated
after we replace `parsec`.
2019-03-25 07:57:12 -07:00

60 lines
2 KiB
Text
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/-
Copyright (c) 2018 Microsoft Corporation. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Leonardo de Moura, Sebastian Ullrich
-/
prelude
import init.data.nat init.data.rbmap init.lean.format init.lean.parser.parsec
namespace Lean
structure Position :=
(line : Nat)
(column : Nat)
namespace Position
instance : DecidableEq Position :=
{decEq := λ ⟨l₁, c₁⟩ ⟨l₂, c₂⟩,
if h₁ : l₁ = l₂ then
if h₂ : c₁ = c₂ then isTrue (Eq.recOn h₁ (Eq.recOn h₂ rfl))
else isFalse (λ contra, Position.noConfusion contra (λ e₁ e₂, absurd e₂ h₂))
else isFalse (λ contra, Position.noConfusion contra (λ e₁ e₂, absurd e₁ h₁))}
protected def lt : Position → Position → Prop
| ⟨l₁, c₁⟩ ⟨l₂, c₂⟩ := (l₁, c₁) < (l₂, c₂)
instance : HasLess Position := ⟨Position.lt⟩
instance decidableLt : Π (p₁ p₂ : Position), Decidable (p₁ < p₂)
| ⟨l₁, c₁⟩ ⟨l₂, c₂⟩ := inferInstanceAs $ Decidable ((l₁, c₁) < (l₂, c₂))
instance : HasToFormat Position :=
⟨λ ⟨l, c⟩, "⟨" ++ toFmt l ++ ", " ++ toFmt c ++ "⟩"⟩
instance : Inhabited Position := ⟨⟨1, 0⟩⟩
end Position
/-- A precomputed cache for quickly mapping Char offsets to positionitions. -/
structure FileMap :=
-- A mapping from Char offset of line start to line index
(lines : RBMap Nat Nat (<))
namespace FileMap
private def fromStringAux : Nat → String.OldIterator → Nat → List (Nat × Nat)
| 0 it line := []
| (k+1) it line :=
if it.hasNext = false then []
else match it.curr with
| '\n' := (it.next.offset, line+1) :: fromStringAux k it.next (line+1)
| other := fromStringAux k it.next line
def fromString (s : String) : FileMap :=
{lines := RBMap.ofList $ fromStringAux s.length s.mkOldIterator 1}
def toPosition (m : FileMap) (off : Nat) : Position :=
match m.lines.lowerBound off with
| some ⟨start, l⟩ := ⟨l, off - start⟩
| none := ⟨1, off⟩
end FileMap
end Lean