-
Notifications
You must be signed in to change notification settings - Fork 172
/
Copy pathSymPath.hs
98 lines (89 loc) · 2.74 KB
/
SymPath.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
{-# LANGUAGE DeriveGeneric #-}
module SymPath
( SymPath (..),
mangle,
pathToC,
consPath,
fromStrings,
)
where
import Data.Char (isAscii, ord)
import Data.Hashable
import GHC.Generics (Generic)
import qualified Map
import Util
-- | The path to a binding
data SymPath = SymPath [String] String deriving (Ord, Eq, Generic)
instance Hashable SymPath
instance Show SymPath where
show (SymPath modulePath symName) =
if null modulePath
then symName
else joinWithPeriod modulePath ++ "." ++ symName
mangle :: String -> String
mangle = ureplace . sreplace . creplace
where
creplace =
replaceChars
( Map.fromList
[ ('+', "_PLUS_"),
('-', "_MINUS_"),
('*', "_MUL_"),
('/', "_DIV_"),
('<', "_LT_"),
('>', "_GT_"),
('?', "_QMARK_"),
('!', "_BANG_"),
('=', "_EQ_")
]
)
sreplace =
replaceStrings
( Map.fromList
[ ("auto", "_AUTO_"),
("break", "_BREAK_"),
("case", "_CASE_"),
("const", "_CONST_"),
("char", "_CHAR_"),
("continue", "_CONTINUE_"),
("default", "_DEFAULT_"),
("do", "_DO_"),
("double", "_DOUBLE_"),
("else", "_ELSE_"),
("enum", "_ENUM_"),
("extern", "_EXTERN"),
("float", "_FLOAT_"),
("for", "_FOR"),
("goto", "_GOTO_"),
("if", "_IF_"),
("int", "_INT_"),
("long", "_LONG_"),
("register", "_REGISTER_"),
("return", "_RETURN_"),
("short", "_SHORT_"),
("signed", "_SIGNED_"),
("sizeof", "_SIZEOF_"),
("static", "_STATIC_"),
("struct", "_STRUCT_"),
("switch", "_SWITCH_"),
("typedef", "_TYPEDEF_"),
("union", "_UNION_"),
("unsigned", "_UNSIGNED_"),
("volatile", "_VOLATILE_"),
("void", "_VOID_"),
("while", "_WHILE_")
]
)
ureplace = concatMap (\c -> if isAscii c then pure c else "_U" ++ show (ord c) ++ "U_")
pathToC :: SymPath -> String
pathToC (SymPath modulePath name) =
concatMap ((++ "_") . mangle) modulePath ++ mangle name
-- | Add qualifying strings to beginning of a path.
consPath :: [String] -> SymPath -> SymPath
consPath qualifyers (SymPath stringPaths name) =
SymPath (qualifyers ++ stringPaths) name
-- | Convert a list of strings into a path.
fromStrings :: [String] -> SymPath
fromStrings [] = SymPath [] ""
fromStrings (s : []) = SymPath [] s
fromStrings ss = SymPath (init ss) (last ss)