vxx2 / vlib / v3 / types / type.v
407 lines · 369 sloc · 6.79 KB · 7a89e581dace12716ed47d2e665fd337d9820870
Raw
1module types
2
3// Type aliases type values used by types.
4pub type Type = Void
5 | Unknown
6 | Primitive
7 | String
8 | Char
9 | Rune
10 | ISize
11 | USize
12 | Nil
13 | None
14 | Array
15 | ArrayFixed
16 | Channel
17 | Map
18 | Pointer
19 | FnType
20 | OptionType
21 | ResultType
22 | Struct
23 | Interface
24 | Enum
25 | SumType
26 | Alias
27 | MultiReturn
28
29// Void represents void data used by types.
30pub struct Void {
31 dummy_ u8
32}
33
34// Unknown represents unknown data used by types.
35pub struct Unknown {
36pub:
37 reason string
38}
39
40// String represents string data used by types.
41pub struct String {
42 dummy_ u8
43}
44
45// Char represents char data used by types.
46pub struct Char {
47 dummy_ u8
48}
49
50// Rune represents rune data used by types.
51pub struct Rune {
52 dummy_ u8
53}
54
55// ISize represents isize data used by types.
56pub struct ISize {
57 dummy_ u8
58}
59
60// USize represents usize data used by types.
61pub struct USize {
62 dummy_ u8
63}
64
65// Nil represents nil data used by types.
66pub struct Nil {
67 dummy_ u8
68}
69
70// None represents none data used by types.
71pub struct None {
72 dummy_ u8
73}
74
75// Properties lists properties values used by types.
76@[flag]
77pub enum Properties {
78 boolean
79 float
80 integer
81 unsigned
82 untyped
83}
84
85// Primitive represents primitive data used by types.
86pub struct Primitive {
87pub:
88 props Properties
89 size u8
90}
91
92// Array represents array data used by types.
93pub struct Array {
94pub:
95 elem_type Type
96}
97
98// ArrayFixed represents array fixed data used by types.
99pub struct ArrayFixed {
100pub:
101 elem_type Type
102 len int
103 len_expr string
104}
105
106// Channel represents channel data used by types.
107pub struct Channel {
108pub:
109 elem_type Type
110}
111
112// Map represents map data used by types.
113pub struct Map {
114pub:
115 key_type Type
116 value_type Type
117}
118
119// Pointer represents pointer data used by types.
120pub struct Pointer {
121pub:
122 base_type Type
123}
124
125// FnType represents fn type data used by types.
126pub struct FnType {
127pub:
128 params []Type
129 return_type Type
130}
131
132// OptionType represents option type data used by types.
133pub struct OptionType {
134pub:
135 base_type Type
136}
137
138// ResultType represents result type data used by types.
139pub struct ResultType {
140pub:
141 base_type Type
142}
143
144// Struct represents struct data used by types.
145pub struct Struct {
146pub:
147 name string
148}
149
150// Interface represents interface data used by types.
151pub struct Interface {
152pub:
153 name string
154}
155
156// Enum represents enum data used by types.
157pub struct Enum {
158pub:
159 name string
160 is_flag bool
161}
162
163// SumType represents sum type data used by types.
164pub struct SumType {
165pub:
166 name string
167}
168
169// Alias represents alias data used by types.
170pub struct Alias {
171pub:
172 name string
173 base_type Type
174}
175
176// MultiReturn represents multi return data used by types.
177pub struct MultiReturn {
178pub:
179 types []Type
180}
181
182// StructField represents struct field data used by types.
183pub struct StructField {
184pub:
185 name string
186 typ Type
187}
188
189// unwrap_pointer transforms unwrap pointer data for types.
190pub fn unwrap_pointer(t Type) Type {
191 if t is Pointer {
192 return t.base_type
193 }
194 return t
195}
196
197// generic_base_name returns the declaration part of a concrete generic type name.
198pub fn generic_base_name(name string) string {
199 if name.starts_with('[') {
200 return name
201 }
202 idx := name.index_u8(`[`)
203 if idx > 0 {
204 return name[..idx]
205 }
206 return name
207}
208
209// is_pointer reports whether is pointer applies in types.
210pub fn (t Type) is_pointer() bool {
211 return t is Pointer
212}
213
214// is_string reports whether is string applies in types.
215pub fn (t Type) is_string() bool {
216 return t is String
217}
218
219// is_integer reports whether is integer applies in types.
220pub fn (t Type) is_integer() bool {
221 if t is Primitive {
222 return t.props.has(.integer)
223 }
224 return t is Rune || t is ISize || t is USize
225}
226
227// is_float reports whether is float applies in types.
228pub fn (t Type) is_float() bool {
229 if t is Primitive {
230 return t.props.has(.float)
231 }
232 return false
233}
234
235// name returns name data for Type.
236pub fn (t Type) name() string {
237 if t is Void {
238 return 'void'
239 }
240 if t is Unknown {
241 return 'unknown'
242 }
243 if t is Nil {
244 return 'nil'
245 }
246 if t is None {
247 return 'none'
248 }
249 if t is String {
250 return 'string'
251 }
252 if t is Char {
253 return 'char'
254 }
255 if t is Rune {
256 return 'rune'
257 }
258 if t is ISize {
259 return 'isize'
260 }
261 if t is USize {
262 return 'usize'
263 }
264 if t is Primitive {
265 return prim_name_from(t.props, t.size)
266 }
267 if t is Array {
268 return '[]${nested_type_name(t.elem_type)}'
269 }
270 if t is ArrayFixed {
271 mut len_text := t.len.str()
272 if t.len_expr.len > 0 {
273 len_text = t.len_expr
274 }
275 return '${nested_type_name(t.elem_type)}[${len_text}]'
276 }
277 if t is Channel {
278 return 'chan ${nested_type_name(t.elem_type)}'
279 }
280 if t is Map {
281 return 'map[${nested_type_name(t.key_type)}]${nested_type_name(t.value_type)}'
282 }
283 if t is Pointer {
284 return '&${nested_type_name(t.base_type)}'
285 }
286 if t is FnType {
287 mut s := 'fn('
288 for i in 0 .. t.params.len {
289 if i > 0 {
290 s += ', '
291 }
292 s += nested_type_name(fn_type_param_type(t, i))
293 }
294 s += ')'
295 if t.return_type !is Void {
296 s += ' ${nested_type_name(t.return_type)}'
297 }
298 return s
299 }
300 if t is OptionType {
301 return '?${nested_type_name(t.base_type)}'
302 }
303 if t is ResultType {
304 return '!${nested_type_name(t.base_type)}'
305 }
306 if t is Struct {
307 return t.name
308 }
309 if t is Interface {
310 return t.name
311 }
312 if t is Enum {
313 return t.name
314 }
315 if t is SumType {
316 return t.name
317 }
318 if t is Alias {
319 return t.name
320 }
321 if t is MultiReturn {
322 mut parts := []string{}
323 for i in 0 .. t.types.len {
324 parts << nested_type_name(t.types[i])
325 }
326 return '(${parts.join(', ')})'
327 }
328 return ''
329}
330
331// nested_type_name supports nested type name handling for types.
332fn nested_type_name(t Type) string {
333 return t.name()
334}
335
336// fn_type_param_type supports fn type param type handling for types.
337fn fn_type_param_type(f FnType, idx int) Type {
338 return f.params[idx]
339}
340
341// prim_name_from supports prim name from handling for types.
342fn prim_name_from(props Properties, size u8) string {
343 if props.has(.boolean) {
344 return 'bool'
345 }
346 if props.has(.integer) {
347 if props.has(.unsigned) {
348 return match size {
349 8 { 'u8' }
350 16 { 'u16' }
351 32 { 'u32' }
352 64 { 'u64' }
353 else { 'u${size}' }
354 }
355 }
356 return match size {
357 0 { 'int' }
358 8 { 'i8' }
359 16 { 'i16' }
360 32 { 'i32' }
361 64 { 'i64' }
362 else { 'i${size}' }
363 }
364 }
365 if props.has(.float) {
366 return match size {
367 32 { 'f32' }
368 64 { 'f64' }
369 else { 'f${size}' }
370 }
371 }
372 return 'int'
373}
374
375// prim_name supports prim name handling for types.
376fn prim_name(t Primitive) string {
377 if t.props.has(.boolean) {
378 return 'bool'
379 }
380 if t.props.has(.integer) {
381 if t.props.has(.unsigned) {
382 return match t.size {
383 8 { 'u8' }
384 16 { 'u16' }
385 32 { 'u32' }
386 64 { 'u64' }
387 else { 'u${t.size}' }
388 }
389 }
390 return match t.size {
391 0 { 'int' }
392 8 { 'i8' }
393 16 { 'i16' }
394 32 { 'i32' }
395 64 { 'i64' }
396 else { 'i${t.size}' }
397 }
398 }
399 if t.props.has(.float) {
400 return match t.size {
401 32 { 'f32' }
402 64 { 'f64' }
403 else { 'f${t.size}' }
404 }
405 }
406 return 'int'
407}
408