Skip to content

Commit 1f0375b

Browse files
committed
Cleanup and formatting
1 parent 4b95bbd commit 1f0375b

File tree

9 files changed

+250
-65
lines changed

9 files changed

+250
-65
lines changed

language-rust.cabal

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,12 @@ flag enableQuasiquotes
2929

3030
library
3131
hs-source-dirs: src
32+
3233
ghc-options: -Wall
34+
-Wincomplete-patterns
35+
-Wincomplete-uni-patterns
36+
-Wmissing-signatures
37+
3338
build-tools: alex, happy
3439
default-language: Haskell2010
3540

@@ -58,7 +63,6 @@ library
5863
, FlexibleInstances
5964
, OverloadedStrings
6065
, OverloadedLists
61-
, StandaloneDeriving
6266
, DeriveFunctor
6367
, DeriveGeneric
6468
, DeriveAnyClass

src/Language/Rust/Data/InputStream.hs

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,20 @@ These are the only functions that need to be implemented in order to use the par
1313

1414
module Language.Rust.Data.InputStream (
1515
-- * InputStream type
16-
InputStream, countLines, inputStreamEmpty,
16+
InputStream,
17+
countLines,
18+
inputStreamEmpty,
19+
1720
-- * Introduction forms
18-
readInputStream, hReadInputStream, inputStreamFromString,
21+
readInputStream,
22+
hReadInputStream,
23+
inputStreamFromString,
24+
1925
-- * Elimination forms
20-
inputStreamToString, takeByte, takeChar, takeChars,
26+
inputStreamToString,
27+
takeByte,
28+
takeChar,
29+
takeChars,
2130
) where
2231

2332
import Data.Word (Word8)
@@ -75,7 +84,7 @@ countLines :: InputStream -> Int
7584
-- | Opaque input type.
7685
newtype InputStream = IS BS.ByteString
7786
takeByte bs = (BS.head (coerce bs), coerce (BS.tail (coerce bs)))
78-
takeChar bs = let Just res = BE.uncons (coerce bs) in coerce res
87+
takeChar bs = maybe (error "takeChar: no char left") coerce (BE.uncons (coerce bs))
7988
inputStreamEmpty = BS.null . coerce
8089
takeChars n = BE.toString . BE.take n . coerce
8190
readInputStream f = coerce <$> BS.readFile f

src/Language/Rust/Data/Position.hs

Lines changed: 55 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,30 @@ Portability : portable
99
1010
Everything to do with describing a position or a contiguous region in a file.
1111
-}
12-
{-# LANGUAGE CPP, DeriveDataTypeable, DeriveGeneric, DeriveAnyClass #-}
12+
{-# LANGUAGE CPP #-}
13+
{-# LANGUAGE DeriveDataTypeable #-}
14+
{-# LANGUAGE DeriveGeneric #-}
15+
{-# LANGUAGE DeriveAnyClass #-}
1316

1417
module Language.Rust.Data.Position (
1518
-- * Positions in files
16-
Position(..), prettyPosition, maxPos, minPos, initPos, incPos, retPos, incOffset,
19+
Position(..),
20+
prettyPosition,
21+
maxPos,
22+
minPos,
23+
initPos,
24+
incPos,
25+
retPos,
26+
incOffset,
27+
1728
-- * Spans in files
18-
Span(..), prettySpan, subsetOf, (#), Spanned(..), Located(..),
29+
Span(..),
30+
unspan,
31+
prettySpan,
32+
subsetOf,
33+
(#),
34+
Spanned(..),
35+
Located(..),
1936
) where
2037

2138
import GHC.Generics (Generic)
@@ -24,8 +41,6 @@ import Data.Data (Data)
2441
import Data.Typeable (Typeable)
2542
import Control.DeepSeq (NFData)
2643

27-
import Data.Ord (comparing)
28-
import Data.List (maximumBy, minimumBy)
2944
import Data.List.NonEmpty (NonEmpty(..))
3045
import Data.Monoid (Monoid(..))
3146
import Data.Semigroup (Semigroup(..))
@@ -43,7 +58,7 @@ data Position = Position {
4358

4459
-- | Pretty print a 'Position'
4560
prettyPosition :: Position -> String
46-
prettyPosition NoPosition = "$"
61+
prettyPosition NoPosition = "???"
4762
prettyPosition (Position _ r c) = show r ++ ":" ++ show c
4863

4964
-- | Maximum of two positions, bias for actual positions.
@@ -54,10 +69,11 @@ prettyPosition (Position _ r c) = show r ++ ":" ++ show c
5469
-- >>> maxPos NoPosition (Position 30 5 8)
5570
-- Position 30 5 8
5671
--
72+
{-# INLINE maxPos #-}
5773
maxPos :: Position -> Position -> Position
5874
maxPos NoPosition p2 = p2
5975
maxPos p1 NoPosition = p1
60-
maxPos p1 p2 = maximumBy (comparing absoluteOffset) [p1,p2]
76+
maxPos p1@(Position a1 _ _) p2@(Position a2 _ _) = if a1 > a2 then p1 else p2
6177

6278
-- | Maximum and minimum positions, bias for actual positions.
6379
--
@@ -67,69 +83,84 @@ maxPos p1 p2 = maximumBy (comparing absoluteOffset) [p1,p2]
6783
-- >>> minPos NoPosition (Position 30 5 8)
6884
-- Position 30 5 8
6985
--
86+
{-# INLINE minPos #-}
7087
minPos :: Position -> Position -> Position
7188
minPos NoPosition p2 = p2
7289
minPos p1 NoPosition = p1
73-
minPos p1 p2 = minimumBy (comparing absoluteOffset) [p1,p2]
90+
minPos p1@(Position a1 _ _) p2@(Position a2 _ _) = if a1 < a2 then p1 else p2
7491

7592
-- | Starting position in a file.
93+
{-# INLINE initPos #-}
7694
initPos :: Position
7795
initPos = Position 0 1 0
7896

7997
-- | Advance columnn a certain number of times.
98+
{-# INLINE incPos #-}
8099
incPos :: Position -> Int -> Position
81100
incPos NoPosition _ = NoPosition
82101
incPos p@Position{ absoluteOffset = a, col = c } offset = p { absoluteOffset = a + offset, col = c + offset }
83102

84103
-- | Advance to the next line.
104+
{-# INLINE retPos #-}
85105
retPos :: Position -> Position
86106
retPos NoPosition = NoPosition
87107
retPos (Position a r _) = Position { absoluteOffset = a + 1, row = r + 1, col = 1 }
88108

89109
-- | Advance only the absolute offset, not the row and column information. Only use this if you
90110
-- know what you are doing!
111+
{-# INLINE incOffset #-}
91112
incOffset :: Position -> Int -> Position
92113
incOffset NoPosition _ = NoPosition
93114
incOffset p@Position{ absoluteOffset = a } offset = p { absoluteOffset = a + offset }
94115

95116
-- | Spans represent a contiguous region of code, delimited by two 'Position's. The endpoints are
96117
-- inclusive. Analogous to the information encoded in a selection.
97-
data Span = Span {
98-
#if __GLASGOW_HASKELL__ >= 820
99-
lo, hi :: {-# UNPACK #-} !Position
100-
#else
101-
lo, hi :: !Position
102-
#endif
103-
} deriving (Eq, Show, Data, Typeable, Generic, NFData)
118+
data Span = Span { lo, hi :: !Position }
119+
deriving (Eq, Show, Data, Typeable, Generic, NFData)
104120

105121
-- | Check if a span is a subset of another span
106122
subsetOf :: Span -> Span -> Bool
107123
Span l1 h1 `subsetOf` Span l2 h2 = minPos l1 l2 == l1 && maxPos h1 h2 == h2
108124

109125
-- | Convenience function lifting '<>' to work on all 'Located' things
126+
{-# INLINE (#) #-}
110127
(#) :: (Located a, Located b) => a -> b -> Span
111128
left # right = spanOf left <> spanOf right
112129

113130
-- | smallest covering 'Span'
114131
instance Semigroup Span where
115-
Span l1 h1 <> Span l2 h2 = Span (minPos l1 l2) (maxPos h1 h2)
132+
{-# INLINE (<>) #-}
133+
Span l1 h1 <> Span l2 h2 = Span (l1 `minPos` l2) (h1 `maxPos` h2)
116134

117135
instance Monoid Span where
136+
{-# INLINE mempty #-}
118137
mempty = Span NoPosition NoPosition
138+
139+
{-# INLINE mappend #-}
119140
mappend = (<>)
120141

121142
-- | Pretty print a 'Span'
122143
prettySpan :: Span -> String
123144
prettySpan (Span lo' hi') = show lo' ++ " - " ++ show hi'
124145

125146
-- | A "tagging" of something with a 'Span' that describes its extent.
126-
data Spanned a = Spanned { unspan :: a, span :: {-# UNPACK #-} !Span } deriving (Data, Typeable, Generic, NFData)
147+
data Spanned a = Spanned a {-# UNPACK #-} !Span
148+
deriving (Data, Typeable, Generic, NFData)
149+
150+
-- | Extract the wrapped value from 'Spanned'
151+
{-# INLINE unspan #-}
152+
unspan :: Spanned a -> a
153+
unspan (Spanned x _) = x
127154

128155
instance Functor Spanned where
156+
{-# INLINE fmap #-}
129157
fmap f (Spanned x s) = Spanned (f x) s
130158

131159
instance Applicative Spanned where
160+
{-# INLINE pure #-}
132161
pure x = Spanned x mempty
162+
163+
{-# INLINE (<*>) #-}
133164
Spanned f s1 <*> Spanned x s2 = Spanned (f x) (s1 <> s2)
134165

135166
instance Monad Spanned where
@@ -149,18 +180,25 @@ class Located a where
149180
spanOf :: a -> Span
150181

151182
instance Located Span where
183+
{-# INLINE spanOf #-}
152184
spanOf = id
153185

154186
instance Located (Spanned a) where
187+
{-# INLINE spanOf #-}
155188
spanOf (Spanned _ s) = s
156189

157190
instance Located a => Located (Maybe a) where
191+
{-# INLINE spanOf #-}
158192
spanOf = foldMap spanOf
159193

194+
-- | /O(n)/ time complexity
160195
instance Located a => Located [a] where
196+
{-# INLINE spanOf #-}
161197
spanOf = foldMap spanOf
162198

199+
-- | /O(n)/ time complexity
163200
instance Located a => Located (NonEmpty a) where
201+
{-# INLINE spanOf #-}
164202
spanOf = foldMap spanOf
165203

166204

src/Language/Rust/Parser/Literals.hs

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@ import Text.Read (readMaybe)
2727

2828
-- | Parse a valid 'LitTok' into a 'Lit'.
2929
translateLit :: LitTok -> Suffix -> a -> Lit a
30-
translateLit (ByteTok s) = let Just (w8,"") = unescapeByte False s in Byte w8
31-
translateLit (CharTok s) = let Just (c,"") = unescapeChar False s in Char c
30+
translateLit (ByteTok s) = Byte (unescapeByte' s)
31+
translateLit (CharTok s) = Char (unescapeChar' s)
3232
translateLit (FloatTok s) = Float (unescapeFloat s)
3333
translateLit (StrTok s) = Str (unfoldr (unescapeChar True) s) Cooked
3434
translateLit (StrRawTok s n) = Str s (Raw n)
@@ -88,6 +88,18 @@ unescapeByte multiline ('\\':c:cs) = case c of
8888
unescapeByte _ (c:cs) = Just (toEnum $ fromEnum c, cs)
8989
unescapeByte _ [] = fail "unescape byte: empty string"
9090

91+
-- | Given a string Rust representation of a character, parse it into a character
92+
unescapeChar' :: String -> Char
93+
unescapeChar' s = case unescapeChar False s of
94+
Just (c, "") -> c
95+
_ -> error "unescape char: bad character literal"
96+
97+
-- | Given a string Rust representation of a byte, parse it into a byte
98+
unescapeByte' :: String -> Word8
99+
unescapeByte' s = case unescapeByte False s of
100+
Just (w8, "") -> w8
101+
_ -> error "unescape byte: bad byte literal"
102+
91103
-- | Given a string Rust representation of an integer, parse it into a number
92104
unescapeInteger :: Num a => String -> (IntRep,a)
93105
unescapeInteger ('0':'b':cs@(_:_)) | all (`elem` "_01") cs = (Bin, numBase 2 (filter (/= '_') cs))

src/Language/Rust/Pretty.hs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ instance Pretty (Item a) where prettyUnresolved = PP.unAnnotate . pret
8888
instance Pretty (Lifetime a) where prettyUnresolved = PP.unAnnotate . prettyAnnUnresolved
8989
instance Pretty (LifetimeDef a) where prettyUnresolved = PP.unAnnotate . prettyAnnUnresolved
9090
instance Pretty (Lit a) where prettyUnresolved = PP.unAnnotate . prettyAnnUnresolved
91+
instance Pretty (Mac a) where prettyUnresolved = PP.unAnnotate . prettyAnnUnresolved
9192
instance Pretty (Nonterminal a) where prettyUnresolved = PP.unAnnotate . prettyAnnUnresolved
9293
instance Pretty (Pat a) where prettyUnresolved = PP.unAnnotate . prettyAnnUnresolved
9394
instance Pretty (Path a) where prettyUnresolved = PP.unAnnotate . prettyAnnUnresolved
@@ -127,6 +128,7 @@ instance PrettyAnnotated Item where prettyAnnUnresolved = printItem
127128
instance PrettyAnnotated Lifetime where prettyAnnUnresolved = printLifetime
128129
instance PrettyAnnotated LifetimeDef where prettyAnnUnresolved = printLifetimeDef
129130
instance PrettyAnnotated Lit where prettyAnnUnresolved = printLit
131+
instance PrettyAnnotated Mac where prettyAnnUnresolved = printMac Paren
130132
instance PrettyAnnotated Nonterminal where prettyAnnUnresolved = printNonterminal
131133
instance PrettyAnnotated Pat where prettyAnnUnresolved = printPat
132134
instance PrettyAnnotated Path where prettyAnnUnresolved = flip printPath False

0 commit comments

Comments
 (0)