swarm-0.7.0.0: src/swarm-lang/Swarm/Language/Syntax/Loc.hs
{-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE UndecidableInstances #-}
-- |
-- SPDX-License-Identifier: BSD-3-Clause
--
-- Types for working with locations of something in source code.
module Swarm.Language.Syntax.Loc (
SrcLoc (..),
Located (..),
LocVar,
srcLocStartsBefore,
srcLocEndsBefore,
) where
import Data.Aeson (FromJSON (..), ToJSON (..), genericParseJSON, genericToJSON)
import Data.Data (Data)
import Data.Hashable (Hashable)
import GHC.Generics (Generic)
import Swarm.Language.Var (Var)
import Swarm.Util.JSON (optionsUntagged)
------------------------------------------------------------
-- SrcLoc
------------------------------------------------------------
-- | The location of something in the textual source code (recorded as
-- an interval measured in terms of indices into the input stream).
data SrcLoc
= NoLoc
| -- | Half-open interval from start (inclusive) to end (exclusive)
SrcLoc Int Int
deriving (Eq, Ord, Show, Data, Generic, Hashable)
instance ToJSON SrcLoc where
toJSON = genericToJSON optionsUntagged
omitField = (== NoLoc)
instance FromJSON SrcLoc where
parseJSON = genericParseJSON optionsUntagged
omittedField = Just NoLoc
-- | @x <> y@ is the smallest 'SrcLoc' that subsumes both @x@ and @y@.
instance Semigroup SrcLoc where
NoLoc <> l = l
l <> NoLoc = l
SrcLoc s1 e1 <> SrcLoc s2 e2 = SrcLoc (min s1 s2) (max e1 e2)
-- | @mempty@ is a special value which means we have no location
-- information.
instance Monoid SrcLoc where
mempty = NoLoc
-- | Check whether one @SrcLoc@ starts before another one,
-- /i.e./ compare their starting indices to see if the first is @<=@
-- the second.
srcLocStartsBefore :: SrcLoc -> SrcLoc -> Bool
srcLocStartsBefore (SrcLoc a _) (SrcLoc b _) = a <= b
srcLocStartsBefore _ _ = False
-- | Check whether the first @SrcLoc@ ends before the second, /i.e./
-- compare their ending indices to see if the first is @<=@ the
-- second.
srcLocEndsBefore :: SrcLoc -> SrcLoc -> Bool
srcLocEndsBefore (SrcLoc _ a) (SrcLoc _ b) = a <= b
srcLocEndsBefore _ _ = False
-- | A variable with associated source location, used for variable
-- binding sites. (Variable occurrences are a bare TVar which gets
-- wrapped in a Syntax node, so we don't need LocVar for those.)
data Located v = LV {lvSrcLoc :: SrcLoc, lvVar :: v}
deriving (Eq, Ord, Functor, Show, Data, Generic, Hashable, FromJSON, ToJSON)
type LocVar = Located Var