{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE TemplateHaskell #-}
module Language.JVM.Attribute.LineNumberTable
( LineNumberTable (..)
, LineNumber
, BinaryFormat
, linenumber
, linenumber'
) where
import Control.DeepSeq (NFData)
import Data.Binary
import qualified Data.IntMap as IM
import GHC.Generics (Generic)
import Language.JVM.Attribute.Base
import Language.JVM.ByteCode
import Language.JVM.Utils
import Language.JVM.Staged
instance IsAttribute (LineNumberTable Low) where
attrName = Const "LineNumberTable"
type LineNumber = Word16
newtype LineNumberTable r = LineNumberTable
{ lineNumberTable :: IM.IntMap LineNumber
} deriving (Show, Eq, Ord, Generic, NFData)
instance ByteCodeStaged LineNumberTable where
evolveBC f (LineNumberTable mp) =
LineNumberTable
. IM.fromList <$> (mapM (\(x, y) -> do x' <- f (fromIntegral x); pure (x', y)) . IM.toList) mp
devolveBC f (LineNumberTable mp) =
LineNumberTable
. IM.fromList <$> (mapM (\(x, y) -> do x' <- f x; pure (fromIntegral x', y)) . IM.toList) mp
linenumber :: Int -> LineNumberTable r -> Maybe LineNumber
linenumber i (LineNumberTable t) =
snd <$> IM.lookupLE i t
linenumber' :: Integral a => a -> LineNumberTable r -> Maybe LineNumber
linenumber' i = linenumber (fromIntegral i)
type BinaryFormat = SizedList16 (Word16, LineNumber)
instance Binary (LineNumberTable Low) where
get = do
LineNumberTable . IM.fromList . map f . unSizedList <$> (get :: Get BinaryFormat)
where
f (a,b) = (fromIntegral a, b)
put (LineNumberTable x) = do
put sl
where
sl :: BinaryFormat
sl = SizedList . map f . IM.toList $ x
f (a,b) = (fromIntegral a, b)