-
Notifications
You must be signed in to change notification settings - Fork 22
/
make-token.hs
173 lines (160 loc) · 4.41 KB
/
make-token.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
{-# LANGUAGE OverloadedStrings #-}
-- Need to fix "Pattern match(es) are overlapped" by hand
module Main where
import Control.Arrow
import Data.Char
import Data.List
main :: IO ()
main = do
putStrLn "{-# LANGUAGE OverloadedStrings #-}"
putStr "\n"
putStrLn "module Token where"
putStr "\n"
putStrLn "import Data.ByteString (ByteString)"
putStrLn "import qualified Data.ByteString as B"
putStrLn "import Data.Ix"
putStr "\n"
putStrLn "-- $setup"
putStrLn "-- >>> :set -XOverloadedStrings"
putStr "\n"
printTokens tokens
putStr "\n"
printDoctests targets
printToToken targets
where
uniqKeys = map head $ group $ map fst staticTableList
tokens = map mkToken uniqKeys
targets = zip uniqKeys tokens
mkToken :: String -> String
mkToken key = "T" ++ concatMap capitalize (splitBy isAlphaNum key)
capitalize :: String -> String
capitalize [] = []
capitalize (x : xs) = toUpper x : xs
splitBy :: (Char -> Bool) -> String -> [String]
splitBy _ [] = []
splitBy p xs
| r == "" = splitBy p xs''
| otherwise = r : splitBy p xs''
where
(r, xs') = span p xs
xs'' = dropWhile (not . p) xs'
printDoctests :: [(String, String)] -> IO ()
printDoctests xs = do
putStrLn "-- |"
putStrLn "--"
mapM_ pr xs
pr ("foo", tokenOther)
where
pr (k, t) = do
putStrLn $ "-- >>> toToken \"" ++ k ++ "\""
putStrLn $ "-- " ++ t
tokenOther :: String
tokenOther = "TOTHER"
printTokens :: [String] -> IO ()
printTokens [] = return ()
printTokens (t : ts) = do
putStrLn $ "data Token = " ++ t
mapM_ pr ts
putStrLn $ " | " ++ tokenOther
putStrLn " deriving (Eq,Ord,Show,Enum,Bounded,Ix)"
where
pr x = putStrLn $ " | " ++ x
printToToken :: [(String, String)] -> IO ()
printToToken xs = do
putStrLn "toToken :: ByteString -> Token"
putStrLn "toToken bs = case len of"
mapM_ printCase ys
putStrLn $ " _ -> " ++ tokenOther
putStrLn " where"
putStrLn " len = B.length bs"
putStrLn " lst = B.last bs"
where
addLen kv@(k, _) = (length k, kv)
extract zs = (l, kv)
where
l = fst $ head zs
(_, kv) = unzip zs
ys = map extract $ groupBy (\x y -> fst x == fst y) $ sort $ map addLen xs
printCase :: (Int, [(String, String)]) -> IO ()
printCase (l, xs) = do
putStrLn $ " " ++ show l ++ " -> case lst of"
mapM_ pr xs'
putStrLn $ " _ -> " ++ tokenOther
where
xs' = map (first reverse) $ sort $ map (first reverse) xs
pr (k, t) = do
putStrLn $
" "
++ show w
++ " -> if bs == \""
++ k
++ "\" then "
++ t
++ " else "
++ tokenOther
where
w = ord $ last k
staticTableList :: [(String, String)]
staticTableList =
[ (":authority", "")
, (":method", "GET")
, (":method", "POST")
, (":path", "/")
, (":path", "/index.html")
, (":scheme", "http")
, (":scheme", "https")
, (":status", "200")
, (":status", "204")
, (":status", "206")
, (":status", "304")
, (":status", "400")
, (":status", "404")
, (":status", "500")
, ("accept-charset", "")
, ("accept-encoding", "gzip, deflate")
, ("accept-language", "")
, ("accept-ranges", "")
, ("accept", "")
, ("access-control-allow-origin", "")
, ("age", "")
, ("allow", "")
, ("authorization", "")
, ("cache-control", "")
, ("content-disposition", "")
, ("content-encoding", "")
, ("content-language", "")
, ("content-length", "")
, ("content-location", "")
, ("content-range", "")
, ("content-type", "")
, ("cookie", "")
, ("date", "")
, ("etag", "")
, ("expect", "")
, ("expires", "")
, ("from", "")
, ("host", "")
, ("if-match", "")
, ("if-modified-since", "")
, ("if-none-match", "")
, ("if-range", "")
, ("if-unmodified-since", "")
, ("last-modified", "")
, ("link", "")
, ("location", "")
, ("max-forwards", "")
, ("proxy-authenticate", "")
, ("proxy-authorization", "")
, ("range", "")
, ("referer", "")
, ("refresh", "")
, ("retry-after", "")
, ("server", "")
, ("set-cookie", "")
, ("strict-transport-security", "")
, ("transfer-encoding", "")
, ("user-agent", "")
, ("vary", "")
, ("via", "")
, ("www-authenticate", "")
]