v2 / vlib / v / ast / comptime_valid_idents.v
261 lines · 255 sloc · 7.36 KB · a1932776a1e2f32ef2ff0f8feab658cf001ef04b
Raw
1module ast
2
3import v.pref
4
5pub const valid_comptime_if_os = ['windows', 'ios', 'macos', 'mac', 'mach', 'darwin', 'hpux', 'gnu',
6 'qnx', 'linux', 'freebsd', 'openbsd', 'netbsd', 'bsd', 'dragonfly', 'android', 'termux',
7 'solaris', 'haiku', 'serenity', 'vinix', 'plan9', 'wasm32_emscripten']
8pub const valid_comptime_if_compilers = ['gcc', 'tinyc', 'clang', 'mingw', 'msvc', 'cplusplus']
9pub const valid_comptime_if_platforms = ['amd64', 'i386', 'aarch64', 'arm64', 'arm32', 'rv64',
10 'rv32', 's390x', 'ppc64le', 'loongarch64', 'sparc64', 'ppc64', 'ppc']
11pub const valid_comptime_if_cpu_features = ['x64', 'x32', 'little_endian', 'big_endian']
12pub const valid_comptime_if_other = ['apk', 'js', 'debug', 'prod', 'test', 'glibc', 'prealloc',
13 'no_bounds_checking', 'freestanding', 'threads', 'js_node', 'js_browser', 'js_freestanding',
14 'interpreter', 'es5', 'profile', 'wasm32', 'wasm32_wasi', 'fast_math', 'autofree']
15pub const valid_comptime_not_user_defined = all_valid_comptime_idents()
16pub const valid_comptime_compression_types = ['none', 'zlib']
17
18fn all_valid_comptime_idents() []string {
19 mut res := []string{}
20 res << valid_comptime_if_os
21 res << valid_comptime_if_compilers
22 res << valid_comptime_if_platforms
23 res << valid_comptime_if_cpu_features
24 res << valid_comptime_if_other
25 return res
26}
27
28pub fn eval_comptime_not_user_defined_ident(ident string, the_pref &pref.Preferences) !bool {
29 mut is_true := false
30 if ident in valid_comptime_if_os {
31 // `$if bsd` is a family predicate matching any BSD-family target
32 // (macos, freebsd, openbsd, netbsd, dragonfly), not a specific OS.
33 if ident == 'bsd' {
34 is_true = the_pref.os in [.macos, .freebsd, .openbsd, .netbsd, .dragonfly]
35 } else if ident_enum_val := pref.os_from_string(ident) {
36 if ident_enum_val == the_pref.os {
37 is_true = true
38 }
39 }
40 } else if ident in valid_comptime_if_compilers {
41 is_true = pref.cc_from_string(ident) == the_pref.ccompiler_type
42 } else if ident in valid_comptime_if_platforms {
43 match ident {
44 'amd64' {
45 is_true = the_pref.arch == .amd64
46 }
47 'i386' {
48 is_true = the_pref.arch == .i386
49 }
50 'aarch64' {
51 is_true = the_pref.arch == .arm64
52 }
53 'arm64' {
54 is_true = the_pref.arch == .arm64
55 }
56 'arm32' {
57 is_true = the_pref.arch == .arm32
58 }
59 'rv64' {
60 is_true = the_pref.arch == .rv64
61 }
62 'rv32' {
63 is_true = the_pref.arch == .rv32
64 }
65 's390x' {
66 is_true = the_pref.arch == .s390x
67 }
68 'ppc64le' {
69 is_true = the_pref.arch == .ppc64le
70 }
71 'loongarch64' {
72 is_true = the_pref.arch == .loongarch64
73 }
74 'sparc64' {
75 is_true = the_pref.arch == .sparc64
76 }
77 'ppc64' {
78 is_true = the_pref.arch == .ppc64
79 }
80 'ppc' {
81 is_true = the_pref.arch == .ppc
82 }
83 else {
84 return error('invalid \$if condition: unknown platforms `${ident}`')
85 }
86 }
87 } else if ident in valid_comptime_if_cpu_features {
88 match ident {
89 'x64' {
90 is_true = the_pref.m64
91 }
92 'x32' {
93 is_true = !the_pref.m64
94 }
95 'little_endian' {
96 // ppc64le is little-endian (the 'le' suffix), all others below are big-endian
97 is_true = the_pref.arch !in [.ppc64, .ppc, .sparc64, .s390x]
98 }
99 'big_endian' {
100 is_true = the_pref.arch in [.ppc64, .ppc, .sparc64, .s390x]
101 }
102 else {
103 return error('invalid \$if condition: unknown cpu_features `${ident}`')
104 }
105 }
106 } else if ident in valid_comptime_if_other {
107 match ident {
108 'apk' {
109 is_true = the_pref.is_apk
110 }
111 'js' {
112 is_true = the_pref.backend.is_js()
113 }
114 'debug' {
115 is_true = the_pref.is_debug
116 }
117 'prod' {
118 is_true = the_pref.is_prod
119 }
120 'test' {
121 is_true = the_pref.is_test
122 }
123 'glibc' {
124 is_true = the_pref.is_glibc
125 }
126 'prealloc' {
127 is_true = the_pref.prealloc
128 }
129 'no_bounds_checking' {
130 is_true = the_pref.no_bounds_checking
131 }
132 'freestanding' {
133 is_true = the_pref.is_bare && !the_pref.output_cross_c
134 }
135 'threads' {
136 return error('threads should handle outside of `check_valid_ident()`')
137 }
138 'js_node' {
139 is_true = the_pref.backend == .js_node
140 }
141 'js_browser' {
142 is_true = the_pref.backend == .js_browser
143 }
144 'js_freestanding' {
145 is_true = the_pref.backend == .js_freestanding
146 }
147 'interpreter' {
148 is_true = the_pref.backend == .interpret
149 }
150 'es5' {
151 is_true = the_pref.output_es5
152 }
153 'profile' {
154 is_true = the_pref.is_prof
155 }
156 'wasm32' {
157 is_true = the_pref.arch == .wasm32
158 }
159 'wasm32_wasi' {
160 is_true = the_pref.os == .wasm32_wasi
161 }
162 'fast_math' {
163 is_true = the_pref.fast_math
164 }
165 'autofree' {
166 is_true = the_pref.autofree
167 }
168 else {
169 return error('invalid \$if condition: unknown other indent `${ident}`')
170 }
171 }
172 } else if ident in the_pref.compile_defines {
173 is_true = true
174 } else {
175 return error('invalid \$if condition: unknown indent `${ident}`')
176 }
177 return is_true
178}
179
180pub const system_ident_map = {
181 // OS
182 'windows': '_WIN32'
183 'ios': '__TARGET_IOS__'
184 'macos': '__APPLE__'
185 'mac': '__APPLE__'
186 'mach': '__MACH__'
187 'darwin': '__DARWIN__'
188 'hpux': '__HPUX__'
189 'gnu': '__GNU__'
190 'qnx': '__QNX__'
191 'linux': '__linux__'
192 'serenity': '__serenity__'
193 'plan9': '__plan9__'
194 'vinix': '__vinix__'
195 'freebsd': '__FreeBSD__'
196 'openbsd': '__OpenBSD__'
197 'netbsd': '__NetBSD__'
198 'bsd': '__BSD__'
199 'dragonfly': '__DragonFly__'
200 'android': '__ANDROID__'
201 'termux': '__TERMUX__'
202 'solaris': '__sun'
203 'haiku': '__HAIKU__'
204 // Backend
205 'js': '_VJS'
206 'wasm32_emscripten': '__EMSCRIPTEN__'
207 // Compiler
208 'gcc': '__V_GCC__'
209 'tinyc': '__TINYC__'
210 'clang': '__clang__'
211 'mingw': '__MINGW32__'
212 'msvc': '_MSC_VER'
213 'cplusplus': '__cplusplus'
214 // Others
215 'threads': '__VTHREADS__'
216 'gcboehm': '_VGCBOEHM'
217 'debug': '_VDEBUG'
218 'prod': '_VPROD'
219 'profile': '_VPROFILE'
220 'test': '_VTEST'
221 'glibc': '__GLIBC__'
222 'prealloc': '_VPREALLOC'
223 'no_bounds_checking': 'CUSTOM_DEFINE_no_bounds_checking'
224 'freestanding': '_VFREESTANDING'
225 'autofree': '_VAUTOFREE'
226 // CPU
227 'amd64': '__V_amd64'
228 'aarch64': '__V_arm64'
229 'arm64': '__V_arm64' // aarch64 alias
230 'arm32': '__V_arm32'
231 'i386': '__V_x86'
232 'rv64': '__V_rv64'
233 'riscv64': '__V_rv64' // rv64 alias
234 'rv32': '__V_rv32'
235 'riscv32': '__V_rv32' // rv32 alias
236 's390x': '__V_s390x'
237 'ppc64le': '__V_ppc64le'
238 'loongarch64': '__V_loongarch64'
239 'sparc64': '__V_sparc64'
240 'ppc': '__V_ppc'
241 'x64': 'TARGET_IS_64BIT'
242 'x32': 'TARGET_IS_32BIT'
243 'little_endian': 'TARGET_ORDER_IS_LITTLE'
244 'big_endian': 'TARGET_ORDER_IS_BIG'
245}
246
247pub fn comptime_if_to_ifdef(name string, the_pref &pref.Preferences) !string {
248 if name == 'fast_math' {
249 return if the_pref.ccompiler_type == .msvc {
250 // turned on by: `-cflags /fp:fast`
251 '_M_FP_FAST'
252 } else {
253 // turned on by: `-cflags -ffast-math`
254 '__FAST_MATH__'
255 }
256 }
257 if ifdef := system_ident_map[name] {
258 return ifdef
259 }
260 return error('bad os ifdef name `${name}`')
261}
262