type.ha (4604B)
1 // SPDX-License-Identifier: MPL-2.0 2 // (c) Hare authors <https://harelang.org> 3 4 use hare::lex; 5 6 // A type alias. 7 export type alias_type = struct { 8 unwrap: bool, 9 ident: ident, 10 }; 11 12 // A built-in primitive type (int, bool, str, etc). 13 export type builtin_type = enum { 14 BOOL, F32, F64, FCONST, I16, I32, I64, I8, ICONST, INT, NEVER, NULL, 15 OPAQUE, RCONST, RUNE, SIZE, STR, U16, U32, U64, U8, UINT, UINTPTR, 16 VALIST, VOID, 17 }; 18 19 // An enumeration field (and optional value). 20 export type enum_field = struct { 21 name: str, 22 value: nullable *expr, 23 loc: lex::location, 24 docs: str, 25 }; 26 27 // enum { FOO = 0, BAR, ... } 28 export type enum_type = struct { 29 storage: builtin_type, 30 values: []enum_field, 31 }; 32 33 // The variadism strategy for a function type. 34 export type variadism = enum { 35 NONE, 36 C, 37 HARE, 38 }; 39 40 // A parameter to a function type. 41 export type func_param = struct { 42 loc: lex::location, 43 name: str, 44 _type: *_type, 45 }; 46 47 // fn(foo: int, baz: int...) int 48 export type func_type = struct { 49 result: *_type, 50 variadism: variadism, 51 params: []func_param, 52 }; 53 54 // The length for a list type which is a slice (e.g. []int). 55 export type len_slice = void; 56 57 // The length for a list type which is unbounded (e.g. [*]int). 58 export type len_unbounded = void; 59 60 // The length for a list type which is inferred from context (e.g. [_]int). 61 export type len_contextual = void; 62 63 // []int, [*]int, [_]int, [foo]int 64 export type list_type = struct { 65 length: (*expr | len_slice | len_unbounded | len_contextual), 66 members: *_type, 67 }; 68 69 // Flags which apply to a pointer type. 70 export type pointer_flag = enum uint { 71 NONE = 0, 72 NULLABLE = 1 << 0, 73 }; 74 75 // *int 76 export type pointer_type = struct { 77 referent: *_type, 78 flags: pointer_flag, 79 }; 80 81 // A single field of a struct type. 82 export type struct_field = struct { 83 name: str, 84 _type: *_type, 85 }; 86 87 // An embedded struct type. 88 export type struct_embedded = *_type; 89 90 // An embedded type alias. 91 export type struct_alias = ident; 92 93 // struct { @offset(10) foo: int, struct { bar: int }, baz::quux } 94 export type struct_member = struct { 95 _offset: nullable *expr, 96 member: (struct_field | struct_embedded | struct_alias), 97 98 // Only valid if the lexer has comments enabled 99 docs: str, 100 }; 101 102 // struct { ... } 103 export type struct_type = struct { 104 packed: bool, 105 members: []struct_member, 106 }; 107 108 // union { ... } 109 export type union_type = []struct_member; 110 111 export type struct_union_type = (struct_type | union_type); 112 113 // (int | bool) 114 export type tagged_type = []*_type; 115 116 // (int, bool, ...) 117 export type tuple_type = []*_type; 118 119 // Flags which apply to types. 120 export type type_flag = enum uint { 121 NONE = 0, 122 CONST = 1 << 0, 123 ERROR = 1 << 1, 124 }; 125 126 // A Hare type. 127 export type _type = struct { 128 start: lex::location, 129 end: lex::location, 130 flags: type_flag, 131 repr: (alias_type | builtin_type | enum_type | func_type | 132 list_type | pointer_type | struct_type | union_type | 133 tagged_type | tuple_type), 134 }; 135 136 fn struct_members_free(membs: []struct_member) void = { 137 for (let i = 0z; i < len(membs); i += 1) { 138 free(membs[i].docs); 139 expr_finish(membs[i]._offset); 140 free(membs[i]._offset); 141 match (membs[i].member) { 142 case let f: struct_field => 143 free(f.name); 144 type_finish(f._type); 145 free(f._type); 146 case let e: struct_embedded => 147 type_finish(e); 148 free(e); 149 case let a: struct_alias => 150 ident_free(a); 151 }; 152 }; 153 free(membs); 154 }; 155 156 // Frees resources associated with a [[_type]]. 157 export fn type_finish(t: nullable *_type) void = match (t) { 158 case null => void; 159 case let t: *_type => 160 match (t.repr) { 161 case let a: alias_type => 162 ident_free(a.ident); 163 case builtin_type => void; 164 case let e: enum_type => 165 for (let i = 0z; i < len(e.values); i += 1) { 166 free(e.values[i].name); 167 expr_finish(e.values[i].value); 168 free(e.values[i].value); 169 }; 170 free(e.values); 171 case let f: func_type => 172 type_finish(f.result); 173 free(f.result); 174 for (let i = 0z; i < len(f.params); i += 1) { 175 free(f.params[i].name); 176 type_finish(f.params[i]._type); 177 free(f.params[i]._type); 178 }; 179 free(f.params); 180 case let l: list_type => 181 match (l.length) { 182 case let e: *expr => 183 expr_finish(e); 184 free(e); 185 case => void; 186 }; 187 type_finish(l.members); 188 free(l.members); 189 case let p: pointer_type => 190 type_finish(p.referent); 191 free(p.referent); 192 case let s: struct_type => 193 struct_members_free(s.members); 194 case let t: tagged_type => 195 for (let i = 0z; i < len(t); i += 1) { 196 type_finish(t[i]); 197 free(t[i]); 198 }; 199 free(t); 200 case let t: tuple_type => 201 for (let i = 0z; i < len(t); i += 1) { 202 type_finish(t[i]); 203 free(t[i]); 204 }; 205 free(t); 206 case let u: union_type => 207 struct_members_free(u); 208 }; 209 };