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