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