v / vlib / v2 / ssa / types.v
138 lines · 123 sloc · 2.97 KB · 81a5657604ec6da99c25e26546870c6888d6fdde
Raw
1// Copyright (c) 2026 Alexander Medvednikov. All rights reserved.
2// Use of this source code is governed by an MIT license
3// that can be found in the LICENSE file.
4
5module ssa
6
7pub type TypeID = int
8
9pub fn (id TypeID) str() string {
10 return int(id).str()
11}
12
13pub enum TypeKind {
14 void_t
15 int_t
16 float_t
17 ptr_t
18 array_t
19 struct_t
20 func_t
21 label_t
22 metadata_t
23}
24
25// str returns the symbolic name for an SSA type kind.
26pub fn (k TypeKind) str() string {
27 return match k {
28 .void_t { 'void_t' }
29 .int_t { 'int_t' }
30 .float_t { 'float_t' }
31 .ptr_t { 'ptr_t' }
32 .array_t { 'array_t' }
33 .struct_t { 'struct_t' }
34 .func_t { 'func_t' }
35 .label_t { 'label_t' }
36 .metadata_t { 'metadata_t' }
37 }
38}
39
40pub struct Type {
41pub:
42 kind TypeKind
43 width int // Bit width
44 elem_type TypeID // For Ptr, Array
45 len int // For Array
46 fields []TypeID // For Structs
47 field_names []string // Field names for Structs
48 params []TypeID // For Funcs
49 ret_type TypeID
50 is_c_struct bool // True for C interop structs (use raw field names, typedef to C struct)
51 is_union bool // True for union types (all fields overlap at offset 0)
52 is_unsigned bool // True for unsigned integer types (u8, u16, u32, u64)
53}
54
55pub struct TypeStore {
56pub mut:
57 types []Type
58 cache map[string]TypeID
59}
60
61pub fn TypeStore.new() &TypeStore {
62 mut ts := &TypeStore{}
63 ts.register(Type{ kind: .void_t }) // ID 0 = Void
64 return ts
65}
66
67pub fn (mut ts TypeStore) get_int(width int) TypeID {
68 key := 'i${width}'
69 if id := map_get_type_id(ts.cache, key) {
70 return id
71 }
72 id := ts.register(Type{ kind: .int_t, width: width })
73 ts.cache[key] = id
74 return id
75}
76
77pub fn (mut ts TypeStore) get_uint(width int) TypeID {
78 key := 'u${width}'
79 if id := map_get_type_id(ts.cache, key) {
80 return id
81 }
82 id := ts.register(Type{ kind: .int_t, width: width, is_unsigned: true })
83 ts.cache[key] = id
84 return id
85}
86
87pub fn (mut ts TypeStore) get_float(width int) TypeID {
88 key := 'f${width}'
89 if id := map_get_type_id(ts.cache, key) {
90 return id
91 }
92 id := ts.register(Type{ kind: .float_t, width: width })
93 ts.cache[key] = id
94 return id
95}
96
97pub fn (mut ts TypeStore) get_ptr(elem TypeID) TypeID {
98 key := 'p${elem}'
99 if id := map_get_type_id(ts.cache, key) {
100 return id
101 }
102 id := ts.register(Type{ kind: .ptr_t, elem_type: elem })
103 ts.cache[key] = id
104 return id
105}
106
107pub fn (mut ts TypeStore) get_array(elem TypeID, length int) TypeID {
108 key := 'a${elem}_${length}'
109 if id := map_get_type_id(ts.cache, key) {
110 return id
111 }
112 id := ts.register(Type{ kind: .array_t, elem_type: elem, len: length })
113 ts.cache[key] = id
114 return id
115}
116
117pub fn (mut ts TypeStore) get_tuple(elem_types []TypeID) TypeID {
118 // Create a cache key from element types
119 mut key := 'tuple'
120 for t in elem_types {
121 key += '_${t}'
122 }
123 if id := map_get_type_id(ts.cache, key) {
124 return id
125 }
126 id := ts.register(Type{
127 kind: .struct_t
128 fields: elem_types
129 })
130 ts.cache[key] = id
131 return id
132}
133
134pub fn (mut ts TypeStore) register(t Type) TypeID {
135 id := ts.types.len
136 ts.types << t
137 return id
138}
139