0 | module Text.WebIDL.Lexer
3 | import Text.Lex.Manual
4 | import Text.WebIDL.Types
12 | keep : IdlToken -> Bool
13 | keep Comment = False
17 | spaces : AutoTok e IdlToken
18 | spaces ('\n' :: xs) = spaces xs
19 | spaces ('\r' :: xs) = spaces xs
20 | spaces ('\t' :: xs) = spaces xs
21 | spaces (' ' :: xs) = spaces xs
22 | spaces xs = Succ Space xs
24 | comment : AutoTok e IdlToken
25 | comment ('\n' :: xs) = Succ Comment ('\n' :: xs)
26 | comment (x :: xs) = comment xs
27 | comment [] = Succ Comment []
29 | mlComment : AutoTok e IdlToken
30 | mlComment ('*' :: '/' :: xs) = Succ Comment xs
31 | mlComment (x :: xs) = mlComment xs
32 | mlComment [] = eoiAt p
34 | string : SnocList Char -> AutoTok e IdlToken
35 | string sc ('"' :: xs) = Succ (SLit $
MkStrLit $
cast sc) xs
36 | string sc (x :: xs) = string (sc :< x) xs
37 | string _ [] = eoiAt p
41 | toIdent : String -> IdlToken
42 | toIdent "Infinity" = FLit Infinity
43 | toIdent "-Infinity" = FLit NegativeInfinity
44 | toIdent "NaN" = FLit NaN
45 | toIdent s = maybe (Ident $
MkIdent s) Key (refineKeyword s)
47 | ident : SnocList Char -> AutoTok e IdlToken
48 | ident sc ('-' :: xs) = ident (sc :< '-') xs
49 | ident sc ('_' :: xs) = ident (sc :< '_') xs
50 | ident sc (x :: xs) =
51 | if isAlphaNum x then ident (sc :< x) xs else Succ (toIdent $
cast sc) (x::xs)
52 | ident sc [] = Succ (toIdent $
cast sc) []
58 | toInt : Signum -> Nat -> Integer
59 | toInt Plus n = cast n
60 | toInt Minus n = negate $
cast n
62 | toNum : Integer -> Maybe Nat -> Maybe Integer -> IdlToken
63 | toNum i Nothing Nothing = ILit $
I i
64 | toNum i mn (Just ex) = FLit $
Exp i mn ex
65 | toNum i (Just ad) Nothing = FLit $
NoExp i ad
67 | exp : Integer -> Maybe Nat -> AutoTok e IdlToken
68 | exp i mn (x :: xs) =
69 | if toLower x == 'e' then toNum i mn . Just <$> autoTok intPlus xs
70 | else Succ (toNum i mn Nothing) (x::xs)
71 | exp i mn [] = Succ (toNum i mn Nothing) []
73 | dot : Integer -> Nat -> AutoTok e IdlToken
75 | if isDigit x then dot i (10*n + digit x) xs else exp i (Just n) (x::xs)
76 | dot i n [] = Succ (toNum i (Just n) Nothing) []
78 | rest : Integer -> AutoTok e IdlToken
79 | rest i ('.'::x::xs) = if isDigit x then dot i (digit x) xs else unknownRange p xs
80 | rest i ('.'::[]) = unknown p
81 | rest i xs = exp i Nothing xs
83 | num : Signum -> Nat -> AutoTok e IdlToken
85 | if isDigit x then num s (n*10 + digit x) xs else rest (toInt s n) (x::xs)
86 | num s n [] = Succ (ILit $
I $
toInt s n) []
92 | isFloat : List Char -> Bool
93 | isFloat ('.' :: _) = True
94 | isFloat ('e' :: _) = True
95 | isFloat ('E' :: _) = True
98 | term : Tok True e IdlToken
99 | term ('"':: xs) = string [<] xs
100 | term ('/'::'/':: xs) = comment xs
101 | term ('/'::'*':: xs) = mlComment xs
102 | term ('0'::'x':: xs) = ILit . Hex <$> hex xs
103 | term ('0'::'X':: xs) = ILit . Hex <$> hex xs
105 | if isFloat xs then rest 0 xs else ILit . Oct <$> oct ('0'::xs)
106 | term ('.'::'.'::'.'::xs) = Succ (Other Ellipsis) xs
107 | term ('_':: x::xs) =
108 | if isAlpha x then ident [<'_',x] xs
109 | else Succ (Other $
Symb '_') (x::xs)
110 | term ('-':: x::xs) =
111 | if isAlpha x then ident [<'-',x] xs
112 | else if isDigit x then num Minus (digit x) xs
113 | else Succ (Other $
Symb '-') (x::xs)
115 | if isAlpha x then ident [<x] xs
116 | else if isDigit x then num Plus (digit x) xs
117 | else if isSpace x then spaces xs
118 | else Succ (Other $
Symb x) xs
119 | term [] = eoiAt Same
123 | ParseErr = InnerError IdlError
126 | SnocList (Bounded IdlToken)
127 | -> (pos : Position)
128 | -> (cs : List Char)
129 | -> (0 acc : SuffixAcc cs)
130 | -> Either (Bounded ParseErr) (List (Bounded IdlToken))
131 | go sx _ [] _ = Right (sx <>> [])
132 | go sx pos xs (SA r) = case term xs of
133 | Succ t xs' @{prf} =>
134 | let pos2 := endPos pos prf
135 | sx' := if keep t then (sx :< bounded t pos pos2) else sx
136 | in go sx' pos2 xs' r
137 | Fail start errEnd r => Left $
boundedErr pos start errEnd r
143 | lexIdl : String -> Either (Bounded ParseErr) (List $
Bounded IdlToken)
144 | lexIdl s = go [<] begin (unpack s) suffixAcc