@@ -5,18 +5,27 @@ module Reporting.Render.Code
55 , toSource
66 , toSnippet
77 , toPair
8+ , Next(..)
9+ , whatIsNext
810 )
911 where
1012
1113
1214import qualified Data.ByteString as B
1315import qualified Data.ByteString.UTF8 as UTF8_BS
16+import qualified Data.Char as Char
17+import qualified Data.IntSet as IntSet
1418import qualified Data.List as List
19+import qualified Data.Name as Name
20+import qualified Data.Set as Set
1521import Data.Word (Word16)
1622
1723import qualified Reporting.Annotation as A
1824import qualified Reporting.Doc as D
1925import Reporting.Doc (Doc)
26+import Parse.Primitives (Row, Col)
27+import Parse.Symbol (binopCharSet)
28+import Parse.Variable (reservedWords)
2029
2130
2231
@@ -180,3 +189,55 @@ renderPair source@(Source sourceLines) region1 region2 =
180189 TwoChunks
181190 (render source region1 Nothing)
182191 (render source region2 Nothing)
192+
193+
194+
195+-- WHAT IS NEXT?
196+
197+
198+data Next
199+ = Spaces
200+ | Keyword String
201+ | Operator String
202+ | CloseParen
203+ | CloseSquare
204+ | CloseCurly
205+ | Other
206+
207+
208+whatIsNext :: Source -> Row -> Col -> Next
209+whatIsNext (Source sourceLines) row col =
210+ case List.lookup row sourceLines of
211+ Nothing ->
212+ Other
213+
214+ Just line ->
215+ let
216+ chars = drop (fromIntegral col - 1) line
217+ in
218+ case List.find (\kwd -> startsWith kwd chars) (map Name.toChars (Set.toList reservedWords)) of
219+ Just keyword ->
220+ Keyword keyword
221+
222+ Nothing ->
223+ case takeWhile isSymbol chars of
224+ op@(_:_) ->
225+ Operator op
226+
227+ []
228+ | null chars -> Spaces
229+ | startsWith " " chars -> Spaces
230+ | startsWith ")" chars -> CloseParen
231+ | startsWith "]" chars -> CloseSquare
232+ | startsWith "}" chars -> CloseCurly
233+ | otherwise -> Other
234+
235+
236+isSymbol :: Char -> Bool
237+isSymbol char =
238+ IntSet.member (Char.ord char) binopCharSet
239+
240+
241+startsWith :: [Char] -> [Char] -> Bool
242+startsWith =
243+ List.isPrefixOf