-
Notifications
You must be signed in to change notification settings - Fork 16
Expand file tree
/
Copy pathtypes.v
More file actions
334 lines (317 loc) · 7.72 KB
/
types.v
File metadata and controls
334 lines (317 loc) · 7.72 KB
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
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
module main
// V type mapping from Python types
pub const v_type_map = {
'int': 'int'
'float': 'f64'
'str': 'string'
'bool': 'bool'
'complex': 'complex128'
'Bool': 'bool' // SMT Bool type
'bytes': '[]u8'
'tuple': '[]int' // V doesn't have tuples, use arrays
'c_int8': 'i8'
'c_int16': 'i16'
'c_int32': 'int'
'c_int64': 'i64'
'c_uint8': 'u8'
'c_uint16': 'u16'
'c_uint32': 'u32'
'c_uint64': 'u64'
'i8': 'i8'
'i16': 'i16'
'i32': 'int'
'i64': 'i64'
'u8': 'u8'
'u16': 'u16'
'u32': 'u32'
'u64': 'u64'
'None': 'Any'
}
// V container type mapping
pub const v_container_type_map = {
'List': '[]'
'list': '[]' // Python 3.9+ lowercase generic
'Dict': 'map'
'dict': 'map' // Python 3.9+ lowercase generic
'Set': '[]' // V doesn't have sets, use arrays
'set': '[]' // Python 3.9+ lowercase generic
'Optional': '?'
'Tuple': '[]' // V doesn't have tuples, use arrays
'tuple': '[]' // Python 3.9+ lowercase generic
}
// V keywords that need escaping with @
pub const v_keywords = [
'as',
'asm',
'assert',
'atomic',
'break',
'const',
'continue',
'defer',
'else',
'enum',
'false',
'for',
'fn',
'__global',
'go',
'goto',
'if',
'import',
'in',
'interface',
'is',
'match',
'module',
'mut',
'shared',
'lock',
'rlock',
'none',
'return',
'select',
'sizeof',
'isreftype',
'_likely_',
'_unlikely_',
'__offsetof',
'struct',
'true',
'type',
'typeof',
'dump',
'or',
'union',
'pub',
'static',
'unsafe',
]!
// V built-in type names that conflict when used as identifiers (variable/parameter names)
// These need escaping with @ only in identifier context, not as type casts
pub const v_builtin_types = [
'string',
'int',
'i8',
'i16',
'i64',
'u8',
'u16',
'u32',
'u64',
'f32',
'f64',
'bool',
'byte',
'rune',
'voidptr',
'charptr',
'byteptr',
]!
// V width rank for numeric type promotion
pub const v_width_rank = {
'bool': 0
'i8': 1
'u8': 2
'byte': 2
'i16': 3
'u16': 4
'int': 5
'u32': 6
'i64': 7
'u64': 8
'f32': 9
'f64': 10
}
// op_to_symbol maps Python AST operator names to V symbols.
pub fn op_to_symbol(op_type string) string {
return match op_type {
'Eq' { '==' }
'NotEq' { '!=' }
'Lt' { '<' }
'LtE' { '<=' }
'Gt' { '>' }
'GtE' { '>=' }
'Is' { '==' }
'IsNot' { '!=' }
'In' { 'in' }
'NotIn' { '!in' }
'Add' { '+' }
'Sub' { '-' }
'Mult' { '*' }
'Div' { '/' }
'FloorDiv' { '/' } // Not floor division in V, handled in visit_binop/visit_aug_assign
'Mod' { '%' }
'Pow' { '**' } // Not a V operator, handled in visit_binop/visit_aug_assign
'LShift' { '<<' }
'RShift' { '>>' }
'BitOr' { '|' }
'BitXor' { '^' }
'BitAnd' { '&' }
'MatMult' { '*' } // No matrix mult in V, fallback to *
'And' { '&&' }
'Or' { '||' }
'Not' { '!' }
'Invert' { '~' }
'UAdd' { '+' }
'USub' { '-' }
else { op_type }
}
}
// map_type maps a Python type annotation string to a V type string.
pub fn map_type(typename string) string {
if typename in v_type_map {
return v_type_map[typename]
}
// Check if it's a container type (uppercase or PEP 585 lowercase)
if typename.starts_with('List[') || typename.starts_with('list[') {
inner := typename[typename.index_u8(`[`) + 1..typename.len - 1]
return '[]${map_type(inner)}'
}
if typename.starts_with('Dict[') || typename.starts_with('dict[') {
// Dict[K, V] / dict[K, V] -> map[K]V
inner := typename[typename.index_u8(`[`) + 1..typename.len - 1]
parts := split_type_args(inner)
if parts.len == 2 {
return 'map[${map_type(parts[0])}]${map_type(parts[1])}'
}
}
if typename.starts_with('Optional[') {
inner := typename[9..typename.len - 1]
return '?${map_type(inner)}'
}
if typename.starts_with('Set[') || typename.starts_with('set[') {
inner := typename[typename.index_u8(`[`) + 1..typename.len - 1]
return '[]${map_type(inner)}' // V doesn't have sets
}
if typename.starts_with('Tuple[') || typename.starts_with('tuple[') {
// Tuples become arrays in V
return '[]Any'
}
// Unknown type, return as-is (might be a user-defined type)
return typename
}
// split_type_args splits type arguments like "str, int" into ["str", "int"].
fn split_type_args(s string) []string {
mut result := []string{}
mut depth := 0
mut start := 0
for i, c in s {
if c == `[` {
depth++
} else if c == `]` {
depth--
} else if c == `,` && depth == 0 {
result << s[start..i].trim_space()
start = i + 1
}
}
if start < s.len {
result << s[start..].trim_space()
}
return result
}
// is_keyword returns true if `name` is a V keyword.
pub fn is_keyword(name string) bool {
return name in v_keywords
}
// escape_keyword escapes `name` with @ if it's a V keyword.
pub fn escape_keyword(name string) string {
if is_keyword(name) {
return '@${name}'
}
return name
}
// escape_identifier escapes names that conflict with V keywords or built-in type names.
pub fn escape_identifier(name string) string {
if is_keyword(name) {
return '@${name}'
}
// V built-in type names can't use @ prefix — rename with underscore suffix
if name in v_builtin_types {
return '${name}_'
}
return name
}
// get_wider_type returns the wider numeric type for binary operations.
pub fn get_wider_type(left_type string, right_type string) string {
left_rank := v_width_rank[left_type] or { -1 }
right_rank := v_width_rank[right_type] or { -1 }
if left_rank > right_rank {
return left_type
}
return right_type
}
// promote_numeric_type promotes numeric types for operations like Add/Mult.
pub fn promote_numeric_type(left_type string, right_type string, op string) string {
// Float always wins
if left_type == 'f64' || right_type == 'f64' || left_type == 'f32' || right_type == 'f32' {
return 'f64'
}
// Sub keeps the wider type (no promotion)
if op == 'Sub' {
return get_wider_type(left_type, right_type)
}
// For Add, Mult: promote to next-wider type
wider := get_wider_type(left_type, right_type)
return match wider {
'i8' { 'i16' }
'u8' { 'u16' }
'i16' { 'int' }
'u16' { 'u32' }
'int' { 'i64' }
'u32' { 'u64' }
'i64' { 'i64' }
'u64' { 'u64' }
else { wider }
}
}
// Default type for unresolved types
pub const default_type = 'Any'
// python_to_v_import maps well-known Python module names to their V equivalents.
// An empty string means "suppress silently" (typing, abc, etc.).
// A '!' prefix means "emit comment only" (no direct V equivalent).
pub const python_to_v_import = {
// stdlib with direct V counterparts
'math': 'math'
'os': 'os'
'os.path': 'os'
'sys': 'os'
're': 'regex'
'json': 'json'
'time': 'time'
'random': 'rand'
'collections': 'datatypes'
'io': 'os'
'pathlib': 'os'
'subprocess': 'os'
'shutil': 'os'
'functools': 'arrays'
'itertools': 'arrays'
// suppress — no V equivalent needed
'typing': ''
'abc': ''
'dataclasses': ''
'__future__': ''
'contextlib': ''
'enum': ''
'copy': ''
'types': ''
'builtins': ''
// no direct V equivalent → emit comment
'threading': '!// import threading: use V goroutines (go fn(){})'
'asyncio': '!// import asyncio: use V goroutines and channels'
'socket': '!// import socket: use V net module'
'http': '!// import http: use V net.http'
'urllib': '!// import urllib: use V net.http'
'requests': '!// import requests: use V net.http'
'logging': 'log'
'argparse': 'flag'
'struct': 'encoding.binary'
'hashlib': 'crypto'
'base64': 'encoding.base64'
'csv': '!// import csv: use V csv or manual parsing'
'sqlite3': 'db.sqlite'
'unittest': '!// import unittest: use V built-in `assert` and `v test`'
'pytest': '!// import pytest: use V built-in `assert` and `v test`'
}