125 lines
2.4 KiB
Idris
125 lines
2.4 KiB
Idris
||| file locations
|
|
module Quox.Loc
|
|
|
|
import public Text.Bounded
|
|
import Data.SortedMap
|
|
import Derive.Prelude
|
|
|
|
%default total
|
|
%language ElabReflection
|
|
|
|
public export
|
|
FileName : Type
|
|
FileName = String
|
|
|
|
%runElab derive "Bounds" [Ord]
|
|
|
|
public export
|
|
data Loc_ = NoLoc | YesLoc FileName Bounds
|
|
%name Loc_ loc
|
|
%runElab derive "Loc_" [Eq, Ord, Show]
|
|
|
|
|
|
||| a wrapper for locations which are always considered equal
|
|
public export
|
|
record Loc where
|
|
constructor L
|
|
val : Loc_
|
|
%name Loc loc
|
|
%runElab derive "Loc" [Show]
|
|
|
|
export %inline Eq Loc where _ == _ = True
|
|
export %inline Ord Loc where compare _ _ = EQ
|
|
|
|
public export %inline
|
|
noLoc : Loc
|
|
noLoc = L NoLoc
|
|
|
|
public export %inline
|
|
makeLoc : FileName -> Bounds -> Loc
|
|
makeLoc = L .: YesLoc
|
|
|
|
|
|
export
|
|
onlyStart_ : Loc_ -> Loc_
|
|
onlyStart_ NoLoc = NoLoc
|
|
onlyStart_ (YesLoc fname (MkBounds sl sc _ _)) =
|
|
YesLoc fname $ MkBounds sl sc sl sc
|
|
|
|
export %inline
|
|
onlyStart : Loc -> Loc
|
|
onlyStart = {val $= onlyStart_}
|
|
|
|
export
|
|
onlyEnd_ : Loc_ -> Loc_
|
|
onlyEnd_ NoLoc = NoLoc
|
|
onlyEnd_ (YesLoc fname (MkBounds _ _ el ec)) =
|
|
YesLoc fname $ MkBounds el ec el ec
|
|
|
|
export %inline
|
|
onlyEnd : Loc -> Loc
|
|
onlyEnd = {val $= onlyEnd_}
|
|
|
|
|
|
export
|
|
extend_ : Loc_ -> Bounds -> Loc_
|
|
extend_ NoLoc _ = NoLoc
|
|
extend_ (YesLoc fname (MkBounds sl1 sc1 el1 ec1)) (MkBounds sl2 sc2 el2 ec2) =
|
|
let (sl, sc) = (sl1, sc1) `min` (sl2, sc2)
|
|
(el, ec) = (el1, ec1) `max` (el2, ec2)
|
|
in
|
|
YesLoc fname $ MkBounds sl sc el ec
|
|
|
|
export
|
|
extend : Loc -> Bounds -> Loc
|
|
extend l b = L $ extend_ l.val b
|
|
|
|
export
|
|
extend' : Loc -> Maybe Bounds -> Loc
|
|
extend' l b = maybe l (extend l) b
|
|
|
|
|
|
namespace Loc_
|
|
export
|
|
(.bounds) : Loc_ -> Maybe Bounds
|
|
(YesLoc _ b).bounds = Just b
|
|
(NoLoc).bounds = Nothing
|
|
|
|
namespace Loc
|
|
export
|
|
(.bounds) : Loc -> Maybe Bounds
|
|
l.bounds = l.val.bounds
|
|
|
|
export %inline
|
|
extendL : Loc -> Loc -> Loc
|
|
extendL l1 l2 = l1 `extend'` l2.bounds
|
|
|
|
|
|
infixr 1 `or_`, `or`
|
|
export %inline
|
|
or_ : Loc_ -> Loc_ -> Loc_
|
|
or_ l1@(YesLoc {}) _ = l1
|
|
or_ NoLoc l2 = l2
|
|
|
|
export %inline
|
|
or : Loc -> Loc -> Loc
|
|
or (L l1) (L l2) = L $ l1 `or_` l2
|
|
|
|
|
|
public export
|
|
interface Located a where (.loc) : a -> Loc
|
|
|
|
public export
|
|
0 Located1 : (a -> Type) -> Type
|
|
Located1 f = forall x. Located (f x)
|
|
|
|
public export
|
|
0 Located2 : (a -> b -> Type) -> Type
|
|
Located2 f = forall x, y. Located (f x y)
|
|
|
|
public export
|
|
interface Located a => Relocatable a where setLoc : Loc -> a -> a
|
|
|
|
public export
|
|
0 Relocatable1 : (a -> Type) -> Type
|
|
Relocatable1 f = forall x. Relocatable (f x)
|