Add byte offsets to Range

This commit is contained in:
Kirill Andreev 2020-04-30 21:06:01 +04:00
parent c603cd399d
commit efe1afb61d
No known key found for this signature in database
GPG Key ID: CF7DA79DE4785A47
6 changed files with 76 additions and 35 deletions

View File

@ -3,3 +3,4 @@ module AST (module M) where
import AST.Types as M import AST.Types as M
import AST.Parser as M import AST.Parser as M
import AST.Pretty ()

View File

@ -0,0 +1,22 @@
module AST.Pretty () where
import AST.Types
import PrettyPrint
import Parser
-- instance Pretty (Contract i) where
-- pp (Contract _ decls) =
-- hang "(* contract *)" 2 do
-- vcat $ map (($$ empty) . pp) decls
-- pp (WrongContract err) =
-- pp err
-- instance Pretty Error where
-- pp
-- instance Pretty (Declaration i) where
-- pp (
-- wrap [l, r] a = hang (hang l 2 r) 0 r

View File

@ -1,5 +1,5 @@
{- annotate tree with ranges, add offsets to ranges, store verbatim in Wrong* -} {- TODO(kirill.andreev): add offsets to ranges, store verbatim in Wrong* -}
module AST.Types where module AST.Types where

View File

@ -42,8 +42,6 @@ getNodeTypesPath = getDataFileName "../pascaligo/src/node-types.json"
data ParseTree = ParseTree data ParseTree = ParseTree
{ ptID :: Int { ptID :: Int
, ptName :: Text.Text , ptName :: Text.Text
, ptStart :: Int
, ptFinish :: Int
, ptRange :: Range , ptRange :: Range
, ptChildren :: ParseForest , ptChildren :: ParseForest
} }
@ -61,16 +59,10 @@ instance Show ParseForest where
show = show . pp show = show . pp
instance Pretty ParseTree where instance Pretty ParseTree where
pp (ParseTree _ n _ _ (Range (sr, sc) (fr, fc)) forest) = pp (ParseTree _ n r forest) =
parens parens
( hang ( hang
( quotes (text (Text.unpack n)) (quotes (text (Text.unpack n)) <+> pp r)
<+> brackets
( int sr <> ":" <> int sc
<> " - "
<> int fr <> ":" <> int fc
)
)
2 2
(pp forest) (pp forest)
) )
@ -123,8 +115,6 @@ toParseTree fin = do
ty <- peekCString $ nodeType node ty <- peekCString $ nodeType node
TSNode start _ _ _ _ <- peek tsNodePtr
let let
start2D = nodeStartPoint node start2D = nodeStartPoint node
finish2D = nodeEndPoint node finish2D = nodeEndPoint node
@ -138,19 +128,19 @@ toParseTree fin = do
{ rStart = { rStart =
( i $ pointRow start2D + 1 ( i $ pointRow start2D + 1
, i $ pointColumn start2D + 1 , i $ pointColumn start2D + 1
, i $ nodeStartByte node
) )
, rFinish = , rFinish =
( i $ pointRow finish2D + 1 ( i $ pointRow finish2D + 1
, i $ pointColumn finish2D + 1 , i $ pointColumn finish2D + 1
, i $ nodeEndByte node
) )
} }
return $ ParseTree return $ ParseTree
{ ptID = treeID { ptID = treeID
, ptName = Text.pack ty , ptName = Text.pack ty
, ptStart = fromIntegral start
, ptFinish = fromIntegral $ nodeEndByte node
, ptRange = range , ptRange = range
, ptChildren = Forest fID trees range , ptChildren = Forest fID trees range
} }

View File

@ -19,8 +19,11 @@ import Range
import Debug.Trace import Debug.Trace
data Error data Error
= Expected Text Range = Expected
| Unexpected Range { eMsg :: Text
, eWhole :: Text
, eRange :: Range
}
deriving stock (Show) deriving stock (Show)
newtype Parser a = Parser newtype Parser a = Parser
@ -42,6 +45,21 @@ newtype Parser a = Parser
, MonadError Error , MonadError Error
) )
makeError :: Text -> Parser Error
makeError msg = do
rng <- getRange
makeError' msg rng
makeError' :: Text -> Range -> Parser Error
makeError' msg rng = do
rng <- getRange
src <- cutOut rng
return Expected
{ eMsg = msg
, eWhole = src
, eRange = rng
}
takeNext :: Text -> Parser ParseTree takeNext :: Text -> Parser ParseTree
takeNext msg = do takeNext msg = do
st@Forest {pfGrove, pfRange} <- get st@Forest {pfGrove, pfRange} <- get
@ -82,11 +100,16 @@ field name parser = do
, pfRange = if firstOne then diffRange rng ptRange else rng , pfRange = if firstOne then diffRange rng ptRange else rng
} }
fallback :: Stubbed a => Text -> Parser a fallback :: Stubbed a => Text -> Parser a
fallback msg = (stub . Expected msg) <$> getRange fallback' :: Stubbed a => Text -> Range -> Parser a
die :: Text -> Parser a
die :: Text -> Parser a die' :: Text -> Range -> Parser a
die msg = throwError . Expected msg =<< getRange complain :: Text -> Range -> Parser ()
fallback msg = pure . stub =<< makeError msg
fallback' msg rng = pure . stub =<< makeError' msg rng
die msg = throwError =<< makeError msg
die' msg rng = throwError =<< makeError' msg rng
complain msg rng = tell . pure =<< makeError' msg rng
stubbed :: Stubbed a => Text -> Parser a -> Parser a stubbed :: Stubbed a => Text -> Parser a -> Parser a
stubbed msg parser = do stubbed msg parser = do
@ -174,33 +197,32 @@ token node = do
tree@ParseTree {ptName, ptRange} <- takeNext node tree@ParseTree {ptName, ptRange} <- takeNext node
if ptName == node if ptName == node
then do then do
source <- asks peSource cutOut ptRange
return (cutOut source tree)
else do else do
throwError $ Expected node ptRange die' node ptRange
anything :: Parser Text anything :: Parser Text
anything = do anything = do
tree <- takeNext "anything" tree <- takeNext "anything"
source <- asks peSource cutOut $ ptRange tree
return (cutOut source tree)
consume :: Text -> Parser () consume :: Text -> Parser ()
consume node = do consume node = do
ParseTree {ptName, ptRange} <- takeNext node ParseTree {ptName, ptRange} <- takeNext node
when (ptName /= node) do when (ptName /= node) do
tell [Expected node ptRange] complain node ptRange
consumeOrDie :: Text -> Parser () consumeOrDie :: Text -> Parser ()
consumeOrDie node = do consumeOrDie node = do
ParseTree {ptName, ptRange} <- takeNext node ParseTree {ptName, ptRange} <- takeNext node
when (ptName /= node) do when (ptName /= node) do
throwError $ Expected node ptRange die' node ptRange
cutOut :: ByteString -> ParseTree -> Text cutOut :: Range -> Parser Text
cutOut bs (ParseTree _ _ s f _ _) = cutOut (Range (_, _, s) (_, _, f)) = do
decodeUtf8 $ ByteString.take (f - s) (ByteString.drop s bs) bs <- asks peSource
return $ decodeUtf8 $ ByteString.take (f - s) (ByteString.drop s bs)
range :: Parser a -> Parser (a, Range) range :: Parser a -> Parser (a, Range)
range parser = range parser =

View File

@ -1,12 +1,18 @@
module Range where module Range where
import PrettyPrint
data Range = Range data Range = Range
{ rStart :: (Int, Int) { rStart :: (Int, Int, Int)
, rFinish :: (Int, Int) , rFinish :: (Int, Int, Int)
} }
deriving stock (Show) deriving stock (Show)
diffRange :: Range -> Range -> Range diffRange :: Range -> Range -> Range
diffRange (Range ws wf) (Range ps _) = Range (max ws ps) wf diffRange (Range ws wf) (Range ps _) = Range (max ws ps) wf
instance Pretty Range where
pp (Range (ll, lc, _) (rl, rc, _)) =
brackets do
int ll <> ":" <> int lc <> "-" <> int rl <> ":" <> int rc