types.c (33668B)
1 #include <string.h> 2 3 #include "internal.h" 4 5 static ToyType* toy_type_slot(ToyParser* p, ToyTypeId id) { 6 if (id == TOY_TYPE_NONE || id > p->module->type_table.ntypes) return NULL; 7 return &p->module->type_table.types[id - 1u]; 8 } 9 10 static ToyTypeId toy_type_find(ToyParser* p, const ToyType* key) { 11 size_t i; 12 for (i = 0; i < p->module->type_table.ntypes; ++i) { 13 ToyType* ty = &p->module->type_table.types[i]; 14 if (ty->kind == key->kind && ty->cg == key->cg && ty->name == key->name && 15 ty->base == key->base && ty->elem == key->elem && 16 ty->pointee == key->pointee && ty->ret == key->ret && 17 ty->count == key->count && ty->address_space == key->address_space && 18 ty->quals == key->quals && ty->nparams == key->nparams && 19 ty->variadic == key->variadic) { 20 size_t j; 21 for (j = 0; j < key->nparams; ++j) { 22 if (ty->params[j] != key->params[j]) break; 23 } 24 if (j == key->nparams) return (ToyTypeId)(i + 1u); 25 } 26 } 27 return TOY_TYPE_NONE; 28 } 29 30 static ToyTypeId toy_type_add(ToyParser* p, const ToyType* type) { 31 ToyTypeId existing = toy_type_find(p, type); 32 if (existing != TOY_TYPE_NONE) return existing; 33 if (!toy_parser_reserve(p, (void**)&p->module->type_table.types, 34 &p->module->type_table.cap_types, 35 p->module->type_table.ntypes + 1u, 36 sizeof *p->module->type_table.types, "toy types")) { 37 return TOY_TYPE_NONE; 38 } 39 p->module->type_table.types[p->module->type_table.ntypes] = *type; 40 p->module->type_table.ntypes++; 41 return (ToyTypeId)p->module->type_table.ntypes; 42 } 43 44 static ToyTypeId toy_type_register(ToyParser* p, ToyTypeKind kind, 45 KitCgTypeId cg, KitSym name, 46 ToyTypeId base) { 47 ToyType type; 48 memset(&type, 0, sizeof type); 49 type.kind = kind; 50 type.cg = cg; 51 type.name = name; 52 type.base = base; 53 return toy_type_add(p, &type); 54 } 55 56 static ToyTypeId toy_type_register_array(ToyParser* p, KitCgTypeId cg, 57 ToyTypeId elem, uint64_t count) { 58 ToyType type; 59 memset(&type, 0, sizeof type); 60 type.kind = TOY_TYPE_ARRAY; 61 type.cg = cg; 62 type.elem = elem; 63 type.count = count; 64 return toy_type_add(p, &type); 65 } 66 67 static KitCgTypeId toy_type_finish(ToyParser* p, KitCgTypeId cg, 68 ToyTypeId toy_type) { 69 p->last_type = toy_type; 70 return cg; 71 } 72 73 KitCgTypeId toy_parse_type(ToyParser* p) { 74 if (p->cur.kind == TOK_IDENT && 75 ((p->cur.text_len == 5 && memcmp(p->cur.text, "const", 5) == 0) || 76 (p->cur.text_len == 8 && memcmp(p->cur.text, "volatile", 8) == 0) || 77 (p->cur.text_len == 8 && memcmp(p->cur.text, "restrict", 8) == 0))) { 78 int is_restrict = 79 p->cur.text_len == 8 && memcmp(p->cur.text, "restrict", 8) == 0; 80 uint32_t qual = is_restrict ? TOY_TYPE_QUAL_RESTRICT 81 : (p->cur.text_len == 5) ? TOY_TYPE_QUAL_CONST 82 : TOY_TYPE_QUAL_VOLATILE; 83 KitCgTypeId qualified_ty; 84 toy_parser_advance(p); 85 qualified_ty = toy_parse_type(p); 86 if (is_restrict && 87 kit_cg_type_kind(p->c, qualified_ty) != KIT_CG_TYPE_PTR) { 88 toy_error(p, p->cur.loc, "restrict requires pointer type"); 89 return KIT_CG_TYPE_NONE; 90 } 91 return toy_type_finish( 92 p, qualified_ty, 93 toy_type_register_qualified(p, qualified_ty, qualified_ty, qual)); 94 } 95 if (toy_parser_match(p, TOK_FN)) { 96 KitCgTypeId* param_types = NULL; 97 KitCgFuncParam* sig_params = NULL; 98 KitCgFuncSig sig; 99 KitCgTypeId ret_type; 100 ToyTypeId ret_toy_type; 101 KitCgTypeId result = KIT_CG_TYPE_NONE; 102 size_t nparams = 0; 103 size_t cap_param_types = 0; 104 ToyTypeId* param_toy_types = NULL; 105 size_t cap_param_toy_types = 0; 106 size_t cap_sig_params = 0; 107 int variadic = 0; 108 size_t i; 109 110 if (!toy_parser_expect(p, TOK_LPAREN)) { 111 toy_error(p, p->cur.loc, "expected '(' after function type"); 112 goto fn_done; 113 } 114 if (p->cur.kind != TOK_RPAREN) { 115 for (;;) { 116 if (p->cur.kind == TOK_DOTDOTDOT) { 117 variadic = 1; 118 toy_parser_advance(p); 119 break; 120 } 121 if (!toy_parser_reserve(p, (void**)¶m_types, &cap_param_types, 122 nparams + 1u, sizeof *param_types, 123 "function type parameters") || 124 !toy_parser_reserve( 125 p, (void**)¶m_toy_types, &cap_param_toy_types, nparams + 1u, 126 sizeof *param_toy_types, "function type source parameters") || 127 !toy_parser_reserve(p, (void**)&sig_params, &cap_sig_params, 128 nparams + 1u, sizeof *sig_params, 129 "function type signature parameters")) { 130 goto fn_done; 131 } 132 param_types[nparams] = toy_parse_type(p); 133 if (param_types[nparams] == KIT_CG_TYPE_NONE) goto fn_done; 134 param_toy_types[nparams] = p->last_type; 135 nparams++; 136 if (p->cur.kind == TOK_COMMA) { 137 toy_parser_advance(p); 138 if (p->cur.kind == TOK_DOTDOTDOT) { 139 variadic = 1; 140 toy_parser_advance(p); 141 break; 142 } 143 } else { 144 break; 145 } 146 } 147 } 148 if (!toy_parser_expect(p, TOK_RPAREN)) { 149 toy_error(p, p->cur.loc, "expected ')' after function type parameters"); 150 goto fn_done; 151 } 152 if (!toy_parser_expect(p, TOK_COLON)) { 153 toy_error(p, p->cur.loc, "expected ':' before function return type"); 154 goto fn_done; 155 } 156 ret_type = toy_parse_type(p); 157 if (ret_type == KIT_CG_TYPE_NONE) goto fn_done; 158 ret_toy_type = p->last_type; 159 160 for (i = 0; i < nparams; i++) sig_params[i].type = param_types[i]; 161 memset(&sig, 0, sizeof sig); 162 sig.result.type = ret_type; 163 sig.params = sig_params; 164 sig.nparams = (uint32_t)nparams; 165 sig.call_conv = KIT_CG_CC_TARGET_C; 166 sig.abi_variadic = variadic; 167 { 168 KitCgTypeId fn_ty = kit_cg_type_func(p->c, sig); 169 result = toy_type_finish( 170 p, fn_ty, 171 toy_type_register_func(p, fn_ty, ret_toy_type, param_toy_types, 172 nparams, variadic)); 173 } 174 fn_done: 175 toy_parser_free_mem(p, param_types, cap_param_types * sizeof *param_types); 176 toy_parser_free_mem(p, param_toy_types, 177 cap_param_toy_types * sizeof *param_toy_types); 178 toy_parser_free_mem(p, sig_params, cap_sig_params * sizeof *sig_params); 179 return result; 180 } 181 if (toy_parser_match(p, TOK_LBRACKET)) { 182 uint64_t count; 183 KitCgTypeId elem; 184 ToyTypeId elem_toy_type; 185 if (toy_parser_match(p, TOK_RBRACKET)) { 186 ToyTypeId slice_toy_type; 187 elem = toy_parse_type(p); 188 if (elem == KIT_CG_TYPE_NONE) return KIT_CG_TYPE_NONE; 189 elem_toy_type = p->last_type; 190 slice_toy_type = toy_type_register_slice(p, elem, elem_toy_type); 191 return toy_type_finish(p, toy_type_cg(p, slice_toy_type), slice_toy_type); 192 } 193 if (p->cur.kind != TOK_NUMBER || p->cur.is_float || p->cur.int_value < 0) { 194 toy_error(p, p->cur.loc, "expected array count"); 195 return KIT_CG_TYPE_NONE; 196 } 197 count = (uint64_t)p->cur.int_value; 198 toy_parser_advance(p); 199 if (!toy_parser_expect(p, TOK_RBRACKET)) { 200 toy_error(p, p->cur.loc, "expected ']' after array count"); 201 return KIT_CG_TYPE_NONE; 202 } 203 elem = toy_parse_type(p); 204 if (elem == KIT_CG_TYPE_NONE) return KIT_CG_TYPE_NONE; 205 elem_toy_type = p->last_type; 206 { 207 KitCgTypeId array_ty = kit_cg_type_array(p->c, elem, count); 208 return toy_type_finish( 209 p, array_ty, 210 toy_type_register_array(p, array_ty, elem_toy_type, count)); 211 } 212 } 213 if (toy_parser_match(p, TOK_RECORD)) { 214 KitCgFieldDesc* fields = NULL; 215 size_t nfields = 0; 216 size_t cap_fields = 0; 217 int packed = 0; 218 uint32_t record_align = 0; 219 KitCgTypeId result = KIT_CG_TYPE_NONE; 220 if (!toy_parse_record_attr_list(p, &packed, &record_align)) 221 return KIT_CG_TYPE_NONE; 222 if (!toy_parser_expect(p, TOK_LBRACE)) { 223 toy_error(p, p->cur.loc, "expected '{' after record type"); 224 goto record_done; 225 } 226 while (p->cur.kind != TOK_RBRACE && p->cur.kind != TOK_EOF) { 227 if (!toy_parser_reserve(p, (void**)&fields, &cap_fields, nfields + 1u, 228 sizeof *fields, "record type fields")) { 229 goto record_done; 230 } 231 if (p->cur.kind != TOK_IDENT) { 232 toy_error(p, p->cur.loc, "expected record field name"); 233 goto record_done; 234 } 235 fields[nfields].name = toy_tok_sym(p, p->cur); 236 toy_parser_advance(p); 237 if (!toy_parse_field_attr_list(p, &fields[nfields])) goto record_done; 238 if (!toy_parser_expect(p, TOK_COLON)) { 239 toy_error(p, p->cur.loc, "expected ':' after record field name"); 240 goto record_done; 241 } 242 fields[nfields].type = toy_parse_type(p); 243 if (fields[nfields].type == KIT_CG_TYPE_NONE) goto record_done; 244 nfields++; 245 if (!toy_parser_match(p, TOK_COMMA)) break; 246 } 247 if (!toy_parser_expect(p, TOK_RBRACE)) { 248 toy_error(p, p->cur.loc, "expected '}' after record type"); 249 goto record_done; 250 } 251 if (packed) { 252 size_t i; 253 for (i = 0; i < nfields; ++i) { 254 if (!fields[i].align_override) fields[i].align_override = 1; 255 } 256 } 257 { 258 KitCgTypeId record_ty = 259 toy_cg_record_type(p, 0, fields, (uint32_t)nfields, 0, record_align); 260 result = toy_type_finish(p, record_ty, toy_type_from_cg(p, record_ty)); 261 } 262 record_done: 263 toy_parser_free_mem(p, fields, cap_fields * sizeof *fields); 264 return result; 265 } 266 if (p->cur.kind == TOK_INT) { 267 toy_error(p, p->cur.loc, 268 "legacy int type is unsupported; use an explicit scalar type"); 269 return KIT_CG_TYPE_NONE; 270 } 271 if (p->cur.kind == TOK_IDENT) { 272 KitCgTypeId ty = KIT_CG_TYPE_NONE; 273 if (p->cur.text_len == 4 && memcmp(p->cur.text, "void", 4) == 0) 274 ty = toy_builtin_type(p, KIT_CG_BUILTIN_VOID); 275 else if (p->cur.text_len == 4 && memcmp(p->cur.text, "bool", 4) == 0) 276 ty = toy_builtin_type(p, KIT_CG_BUILTIN_BOOL); 277 else if (p->cur.text_len == 2 && p->cur.text[0] == 'i' && 278 p->cur.text[1] == '8') 279 ty = toy_builtin_type(p, KIT_CG_BUILTIN_I8); 280 else if (p->cur.text_len == 2 && p->cur.text[0] == 'u' && 281 p->cur.text[1] == '8') 282 ty = toy_builtin_type(p, KIT_CG_BUILTIN_I8); 283 else if (p->cur.text_len == 3 && p->cur.text[0] == 'i' && 284 p->cur.text[1] == '1' && p->cur.text[2] == '6') 285 ty = toy_builtin_type(p, KIT_CG_BUILTIN_I16); 286 else if (p->cur.text_len == 3 && p->cur.text[0] == 'u' && 287 p->cur.text[1] == '1' && p->cur.text[2] == '6') 288 ty = toy_builtin_type(p, KIT_CG_BUILTIN_I16); 289 else if (p->cur.text_len == 3 && p->cur.text[0] == 'i' && 290 p->cur.text[1] == '3' && p->cur.text[2] == '2') 291 ty = toy_builtin_type(p, KIT_CG_BUILTIN_I32); 292 else if (p->cur.text_len == 3 && p->cur.text[0] == 'u' && 293 p->cur.text[1] == '3' && p->cur.text[2] == '2') 294 ty = toy_builtin_type(p, KIT_CG_BUILTIN_I32); 295 else if (p->cur.text_len == 3 && p->cur.text[0] == 'i' && 296 p->cur.text[1] == '6' && p->cur.text[2] == '4') 297 ty = toy_builtin_type(p, KIT_CG_BUILTIN_I64); 298 else if (p->cur.text_len == 3 && p->cur.text[0] == 'u' && 299 p->cur.text[1] == '6' && p->cur.text[2] == '4') 300 ty = toy_builtin_type(p, KIT_CG_BUILTIN_I64); 301 else if (p->cur.text_len == 4 && p->cur.text[0] == 'i' && 302 p->cur.text[1] == '1' && p->cur.text[2] == '2' && 303 p->cur.text[3] == '8') 304 ty = toy_builtin_type(p, KIT_CG_BUILTIN_I128); 305 else if (p->cur.text_len == 4 && p->cur.text[0] == 'u' && 306 p->cur.text[1] == '1' && p->cur.text[2] == '2' && 307 p->cur.text[3] == '8') 308 ty = toy_builtin_type(p, KIT_CG_BUILTIN_I128); 309 else if (p->cur.text_len == 5 && memcmp(p->cur.text, "isize", 5) == 0) 310 ty = p->size_type; 311 else if (p->cur.text_len == 5 && memcmp(p->cur.text, "usize", 5) == 0) 312 ty = p->size_type; 313 else if (p->cur.text_len == 3 && memcmp(p->cur.text, "f32", 3) == 0) 314 ty = toy_builtin_type(p, KIT_CG_BUILTIN_F32); 315 else if (p->cur.text_len == 3 && memcmp(p->cur.text, "f64", 3) == 0) 316 ty = toy_builtin_type(p, KIT_CG_BUILTIN_F64); 317 else if (p->cur.text_len == 7 && memcmp(p->cur.text, "va_list", 7) == 0) 318 ty = p->va_list_type; 319 else { 320 ToyNamedType* named = toy_find_named_type(p, toy_tok_sym(p, p->cur)); 321 if (named) { 322 if (named->type == KIT_CG_TYPE_NONE || 323 ((named->kind == TOY_NAMED_RECORD || 324 named->kind == TOY_NAMED_TUPLE) && 325 !kit_cg_type_is_complete(p->c, named->type))) { 326 toy_error(p, p->cur.loc, "incomplete record type requires pointer"); 327 return KIT_CG_TYPE_NONE; 328 } 329 ty = named->type; 330 } 331 } 332 if (ty != KIT_CG_TYPE_NONE) { 333 ToyTypeId toy_type = toy_type_from_cg(p, ty); 334 ToyNamedType* named = (p->cur.kind == TOK_IDENT) 335 ? toy_find_named_type(p, toy_tok_sym(p, p->cur)) 336 : NULL; 337 if (named && named->type == ty && named->toy_type != TOY_TYPE_NONE) 338 toy_type = named->toy_type; 339 toy_parser_advance(p); 340 return toy_type_finish(p, ty, toy_type); 341 } 342 } 343 if (toy_parser_match(p, TOK_STAR)) { 344 uint32_t address_space = 0; 345 ToyNamedType* incomplete_pointee = NULL; 346 if (p->cur.kind == TOK_IDENT && p->cur.text_len == 9 && 347 memcmp(p->cur.text, "addrspace", 9) == 0) { 348 int64_t as_value; 349 toy_parser_advance(p); 350 if (!toy_parser_expect(p, TOK_LPAREN) || 351 !toy_parse_number_arg(p, &as_value) || 352 !toy_parser_expect(p, TOK_RPAREN) || as_value < 0) { 353 toy_error(p, p->cur.loc, "invalid address space"); 354 return KIT_CG_TYPE_NONE; 355 } 356 address_space = (uint32_t)as_value; 357 } 358 if (p->cur.kind == TOK_IDENT) { 359 incomplete_pointee = toy_find_named_type(p, toy_tok_sym(p, p->cur)); 360 if (incomplete_pointee && 361 (incomplete_pointee->kind == TOY_NAMED_RECORD || 362 incomplete_pointee->kind == TOY_NAMED_TUPLE) && 363 incomplete_pointee->type != KIT_CG_TYPE_NONE && 364 !kit_cg_type_is_complete(p->c, incomplete_pointee->type)) { 365 KitCgTypeId ptr_ty; 366 toy_parser_advance(p); 367 ptr_ty = kit_cg_type_ptr(p->c, incomplete_pointee->type, address_space); 368 return toy_type_finish( 369 p, ptr_ty, 370 toy_type_register_ptr(p, ptr_ty, incomplete_pointee->toy_type, 371 address_space)); 372 } 373 } 374 { 375 KitCgTypeId pointee = toy_parse_type(p); 376 ToyTypeId pointee_toy_type; 377 if (pointee == KIT_CG_TYPE_NONE) { 378 toy_error(p, p->cur.loc, "expected type after '*'"); 379 return KIT_CG_TYPE_NONE; 380 } 381 pointee_toy_type = p->last_type; 382 { 383 KitCgTypeId ptr_ty = kit_cg_type_ptr(p->c, pointee, address_space); 384 return toy_type_finish( 385 p, ptr_ty, 386 toy_type_register_ptr(p, ptr_ty, pointee_toy_type, address_space)); 387 } 388 } 389 } 390 toy_error(p, p->cur.loc, "expected type"); 391 return KIT_CG_TYPE_NONE; 392 } 393 394 int toy_type_is_intlike(ToyParser* p, KitCgTypeId ty) { 395 KitCgTypeKind k = kit_cg_type_kind(p->c, ty); 396 return k == KIT_CG_TYPE_INT || k == KIT_CG_TYPE_BOOL || k == KIT_CG_TYPE_ENUM; 397 } 398 399 int toy_type_is_float(ToyParser* p, KitCgTypeId ty) { 400 return kit_cg_type_kind(p->c, ty) == KIT_CG_TYPE_FLOAT; 401 } 402 403 int toy_type_is_ptr(ToyParser* p, KitCgTypeId ty) { 404 return kit_cg_type_kind(p->c, ty) == KIT_CG_TYPE_PTR; 405 } 406 407 uint32_t toy_type_int_width(ToyParser* p, KitCgTypeId ty) { 408 if (kit_cg_type_kind(p->c, ty) == KIT_CG_TYPE_BOOL) return 1; 409 return kit_cg_type_int_width(p->c, ty); 410 } 411 412 KitCgTypeId toy_ptr_pointee_func_type(ToyParser* p, KitCgTypeId ptr_ty) { 413 KitCgTypeId fn_ty; 414 if (kit_cg_type_kind(p->c, ptr_ty) != KIT_CG_TYPE_PTR) 415 return KIT_CG_TYPE_NONE; 416 fn_ty = kit_cg_type_ptr_pointee(p->c, ptr_ty); 417 if (kit_cg_type_kind(p->c, fn_ty) != KIT_CG_TYPE_FUNC) 418 return KIT_CG_TYPE_NONE; 419 return fn_ty; 420 } 421 422 void toy_type_register_builtins(ToyParser* p) { 423 size_t i; 424 for (i = 0; i < KIT_CG_BUILTIN_COUNT; ++i) 425 (void)toy_type_from_cg(p, toy_builtin_type(p, (KitCgBuiltinType)i)); 426 (void)toy_type_from_cg(p, p->int_ptr_type); 427 } 428 429 const ToyType* toy_type_get(ToyParser* p, ToyTypeId id) { 430 return toy_type_slot(p, id); 431 } 432 433 KitCgTypeId toy_type_cg(ToyParser* p, ToyTypeId id) { 434 const ToyType* type = toy_type_get(p, id); 435 return type ? type->cg : KIT_CG_TYPE_NONE; 436 } 437 438 ToyTypeId toy_type_from_cg(ToyParser* p, KitCgTypeId cg) { 439 ToyType type; 440 KitCgTypeKind kind; 441 size_t i; 442 if (cg == KIT_CG_TYPE_NONE) return TOY_TYPE_NONE; 443 for (i = 0; i < p->module->type_table.ntypes; ++i) { 444 ToyType* existing = &p->module->type_table.types[i]; 445 if (existing->cg == cg && (existing->kind == TOY_TYPE_NOMINAL_RECORD || 446 existing->kind == TOY_TYPE_TUPLE_RECORD || 447 existing->kind == TOY_TYPE_ENUM)) { 448 return (ToyTypeId)(i + 1u); 449 } 450 if (existing->cg == cg && existing->name == 0 && 451 (existing->kind == TOY_TYPE_BUILTIN || 452 existing->kind == TOY_TYPE_ARRAY || existing->kind == TOY_TYPE_PTR || 453 existing->kind == TOY_TYPE_FUNC || 454 existing->kind == TOY_TYPE_ANON_RECORD)) { 455 return (ToyTypeId)(i + 1u); 456 } 457 } 458 459 memset(&type, 0, sizeof type); 460 type.cg = cg; 461 kind = kit_cg_type_kind(p->c, cg); 462 switch (kind) { 463 case KIT_CG_TYPE_VOID: 464 case KIT_CG_TYPE_BOOL: 465 case KIT_CG_TYPE_INT: 466 case KIT_CG_TYPE_FLOAT: 467 case KIT_CG_TYPE_VARARG_STATE: 468 type.kind = TOY_TYPE_BUILTIN; 469 break; 470 case KIT_CG_TYPE_PTR: 471 type.kind = TOY_TYPE_PTR; 472 type.pointee = toy_type_from_cg(p, kit_cg_type_ptr_pointee(p->c, cg)); 473 type.address_space = kit_cg_type_ptr_address_space(p->c, cg); 474 break; 475 case KIT_CG_TYPE_ARRAY: 476 type.kind = TOY_TYPE_ARRAY; 477 type.elem = toy_type_from_cg(p, kit_cg_type_array_elem(p->c, cg)); 478 type.count = kit_cg_type_array_count(p->c, cg); 479 break; 480 case KIT_CG_TYPE_FUNC: 481 type.kind = TOY_TYPE_FUNC; 482 type.ret = toy_type_from_cg(p, toy_cg_func_ret(p, cg)); 483 type.count = kit_cg_type_func_nparams(p->c, cg); 484 break; 485 case KIT_CG_TYPE_RECORD: 486 type.kind = TOY_TYPE_ANON_RECORD; 487 type.count = kit_cg_type_record_nfields(p->c, cg); 488 break; 489 case KIT_CG_TYPE_ENUM: 490 type.kind = TOY_TYPE_ENUM; 491 break; 492 } 493 return toy_type_add(p, &type); 494 } 495 496 ToyTypeId toy_type_register_alias(ToyParser* p, KitSym name, KitCgTypeId cg, 497 KitCgTypeId base) { 498 ToyType type; 499 memset(&type, 0, sizeof type); 500 type.kind = TOY_TYPE_ALIAS; 501 type.cg = cg; 502 type.name = name; 503 type.base = toy_type_from_cg(p, base); 504 return toy_type_add(p, &type); 505 } 506 507 ToyTypeId toy_type_register_named_record(ToyParser* p, KitSym name, 508 KitCgTypeId cg, int is_tuple) { 509 ToyTypeKind kind = is_tuple ? TOY_TYPE_TUPLE_RECORD : TOY_TYPE_NOMINAL_RECORD; 510 size_t i; 511 for (i = 0; i < p->module->type_table.ntypes; ++i) { 512 ToyType* type = &p->module->type_table.types[i]; 513 if (type->kind == kind && type->name == name) { 514 if (type->cg == KIT_CG_TYPE_NONE && cg != KIT_CG_TYPE_NONE) { 515 if (!toy_txn_record_type(p, i)) return TOY_TYPE_NONE; 516 type->cg = cg; 517 } 518 return (ToyTypeId)(i + 1u); 519 } 520 } 521 return toy_type_register(p, kind, cg, name, TOY_TYPE_NONE); 522 } 523 524 ToyTypeId toy_type_register_enum(ToyParser* p, KitSym name, KitCgTypeId cg, 525 KitCgTypeId base) { 526 ToyType type; 527 memset(&type, 0, sizeof type); 528 type.kind = TOY_TYPE_ENUM; 529 type.cg = cg; 530 type.name = name; 531 type.base = toy_type_from_cg(p, base); 532 return toy_type_add(p, &type); 533 } 534 535 ToyTypeId toy_type_register_qualified(ToyParser* p, KitCgTypeId cg, 536 KitCgTypeId base, uint32_t quals) { 537 ToyType type; 538 memset(&type, 0, sizeof type); 539 type.kind = TOY_TYPE_QUALIFIED; 540 type.cg = cg; 541 type.base = toy_type_from_cg(p, base); 542 type.quals = quals; 543 return toy_type_add(p, &type); 544 } 545 546 ToyTypeId toy_type_register_ptr(ToyParser* p, KitCgTypeId cg, ToyTypeId pointee, 547 uint32_t address_space) { 548 ToyType type; 549 memset(&type, 0, sizeof type); 550 type.kind = TOY_TYPE_PTR; 551 type.cg = cg; 552 type.pointee = pointee; 553 type.address_space = address_space; 554 return toy_type_add(p, &type); 555 } 556 557 ToyTypeId toy_type_register_slice(ToyParser* p, KitCgTypeId elem_cg, 558 ToyTypeId elem) { 559 KitCgFieldDesc fields[2]; 560 KitCgTypeId ptr_ty; 561 ToyType type; 562 size_t i; 563 if (elem == TOY_TYPE_NONE || elem_cg == KIT_CG_TYPE_NONE) 564 return TOY_TYPE_NONE; 565 for (i = 0; i < p->module->type_table.ntypes; ++i) { 566 ToyType* existing = &p->module->type_table.types[i]; 567 if (existing->kind == TOY_TYPE_SLICE && existing->elem == elem) 568 return (ToyTypeId)(i + 1u); 569 } 570 ptr_ty = kit_cg_type_ptr(p->c, elem_cg, 0); 571 memset(fields, 0, sizeof fields); 572 fields[0].name = kit_sym_intern(p->c, KIT_SLICE_LIT("ptr")); 573 fields[0].type = ptr_ty; 574 fields[1].name = kit_sym_intern(p->c, KIT_SLICE_LIT("len")); 575 fields[1].type = p->size_type; 576 memset(&type, 0, sizeof type); 577 type.kind = TOY_TYPE_SLICE; 578 type.cg = toy_cg_record_type(p, 0, fields, 2, 0, 0); 579 type.elem = elem; 580 return toy_type_add(p, &type); 581 } 582 583 ToyTypeId toy_type_register_func(ToyParser* p, KitCgTypeId cg, ToyTypeId ret, 584 const ToyTypeId* params, size_t nparams, 585 int variadic) { 586 ToyType type; 587 ToyTypeId id; 588 memset(&type, 0, sizeof type); 589 type.kind = TOY_TYPE_FUNC; 590 type.cg = cg; 591 type.ret = ret; 592 type.count = nparams; 593 type.nparams = nparams; 594 type.variadic = variadic; 595 if (nparams) { 596 type.params = (ToyTypeId*)toy_parser_zalloc(p, nparams, sizeof *type.params, 597 "function type parameters"); 598 if (!type.params) return TOY_TYPE_NONE; 599 memcpy(type.params, params, nparams * sizeof *type.params); 600 } 601 id = toy_type_add(p, &type); 602 if (id == TOY_TYPE_NONE || 603 p->module->type_table.types[id - 1u].params != type.params) 604 toy_parser_free_mem(p, type.params, nparams * sizeof *type.params); 605 return id; 606 } 607 608 KitCgTypeId toy_type_resolved_cg(ToyParser* p, ToyTypeId id) { 609 const ToyType* type = toy_type_get(p, id); 610 if (!type) return KIT_CG_TYPE_NONE; 611 if (type->kind == TOY_TYPE_ALIAS || type->kind == TOY_TYPE_QUALIFIED) 612 return toy_type_resolved_cg(p, type->base); 613 if (type->kind == TOY_TYPE_PTR && type->pointee != TOY_TYPE_NONE) { 614 KitCgTypeId pointee = toy_type_resolved_cg(p, type->pointee); 615 if (pointee != KIT_CG_TYPE_NONE) 616 return kit_cg_type_ptr(p->c, pointee, type->address_space); 617 } 618 return type->cg; 619 } 620 621 ToyTypeId toy_type_pointee(ToyParser* p, ToyTypeId id) { 622 const ToyType* type = toy_type_get(p, id); 623 if (!type) return TOY_TYPE_NONE; 624 if (type->kind == TOY_TYPE_ALIAS || type->kind == TOY_TYPE_QUALIFIED) 625 return toy_type_pointee(p, type->base); 626 return type->kind == TOY_TYPE_PTR ? type->pointee : TOY_TYPE_NONE; 627 } 628 629 ToyTypeId toy_type_array_elem(ToyParser* p, ToyTypeId id) { 630 const ToyType* type = toy_type_get(p, id); 631 if (!type) return TOY_TYPE_NONE; 632 if (type->kind == TOY_TYPE_ALIAS || type->kind == TOY_TYPE_QUALIFIED) 633 return toy_type_array_elem(p, type->base); 634 return type->kind == TOY_TYPE_ARRAY ? type->elem : TOY_TYPE_NONE; 635 } 636 637 ToyTypeId toy_type_slice_elem(ToyParser* p, ToyTypeId id) { 638 const ToyType* type = toy_type_get(p, id); 639 if (!type) return TOY_TYPE_NONE; 640 if (type->kind == TOY_TYPE_ALIAS || type->kind == TOY_TYPE_QUALIFIED) 641 return toy_type_slice_elem(p, type->base); 642 return type->kind == TOY_TYPE_SLICE ? type->elem : TOY_TYPE_NONE; 643 } 644 645 int toy_type_is_slice(ToyParser* p, ToyTypeId id) { 646 const ToyType* type = toy_type_get(p, id); 647 if (!type) return 0; 648 if (type->kind == TOY_TYPE_ALIAS || type->kind == TOY_TYPE_QUALIFIED) 649 return toy_type_is_slice(p, type->base); 650 return type->kind == TOY_TYPE_SLICE; 651 } 652 653 static int toy_anon_record_types_match(ToyParser* p, KitCgTypeId expected, 654 KitCgTypeId actual) { 655 uint32_t i; 656 const KitCgRecordLayout* el; 657 const KitCgRecordLayout* al; 658 if (kit_cg_type_kind(p->c, expected) != KIT_CG_TYPE_RECORD || 659 kit_cg_type_kind(p->c, actual) != KIT_CG_TYPE_RECORD) { 660 return 0; 661 } 662 el = kit_cg_type_record_layout(p->c, expected); 663 al = kit_cg_type_record_layout(p->c, actual); 664 if (!el || !al) return 0; 665 if (el->nfields != al->nfields) return 0; 666 for (i = 0; i < el->nfields; ++i) { 667 if (el->fields[i].name != al->fields[i].name) return 0; 668 if (el->fields[i].type != al->fields[i].type) return 0; 669 } 670 return 1; 671 } 672 673 static int toy_type_accepts_storage_type(ToyParser* p, ToyTypeId expected, 674 ToyTypeId actual) { 675 const ToyType* exp = toy_type_get(p, expected); 676 const ToyType* act = toy_type_get(p, actual); 677 KitCgTypeId exp_cg, act_cg; 678 if (!exp || !act) return 0; 679 if (expected == actual) return 1; 680 if (exp->kind == TOY_TYPE_ALIAS || exp->kind == TOY_TYPE_QUALIFIED) 681 return toy_type_accepts_storage_type(p, exp->base, actual); 682 if (act->kind == TOY_TYPE_ALIAS || act->kind == TOY_TYPE_QUALIFIED) 683 return toy_type_accepts_storage_type(p, expected, act->base); 684 if (exp->kind == TOY_TYPE_PTR && act->kind == TOY_TYPE_PTR) { 685 if (exp->address_space != act->address_space) return 0; 686 if (exp->pointee == TOY_TYPE_NONE || act->pointee == TOY_TYPE_NONE) 687 return exp->cg == act->cg; 688 return toy_type_accepts_storage_type(p, exp->pointee, act->pointee); 689 } 690 if (exp->kind == TOY_TYPE_ARRAY && act->kind == TOY_TYPE_ARRAY) { 691 return exp->count == act->count && 692 toy_type_accepts_storage_type(p, exp->elem, act->elem); 693 } 694 if (exp->kind == TOY_TYPE_SLICE && act->kind == TOY_TYPE_SLICE) 695 return toy_type_accepts_storage_type(p, exp->elem, act->elem); 696 if (exp->kind == TOY_TYPE_FUNC && act->kind == TOY_TYPE_FUNC) { 697 size_t i; 698 if (exp->nparams != act->nparams || exp->variadic != act->variadic) 699 return 0; 700 if (!toy_type_accepts_storage_type(p, exp->ret, act->ret)) return 0; 701 if (!exp->params || !act->params) return exp->cg == act->cg; 702 for (i = 0; i < exp->nparams; ++i) { 703 if (!toy_type_accepts_storage_type(p, exp->params[i], act->params[i])) 704 return 0; 705 } 706 return 1; 707 } 708 if (exp->kind == TOY_TYPE_ANON_RECORD && act->kind == TOY_TYPE_ANON_RECORD) 709 return toy_anon_record_types_match(p, exp->cg, act->cg); 710 if (exp->kind == TOY_TYPE_NOMINAL_RECORD || 711 exp->kind == TOY_TYPE_TUPLE_RECORD || exp->kind == TOY_TYPE_ENUM || 712 act->kind == TOY_TYPE_NOMINAL_RECORD || 713 act->kind == TOY_TYPE_TUPLE_RECORD || act->kind == TOY_TYPE_ENUM) 714 return 0; 715 exp_cg = toy_type_resolved_cg(p, expected); 716 act_cg = toy_type_resolved_cg(p, actual); 717 return exp_cg != KIT_CG_TYPE_NONE && exp_cg == act_cg; 718 } 719 720 int toy_type_accepts_storage(ToyParser* p, ToyTypeId expected, 721 ToyTypeId actual) { 722 return toy_type_accepts_storage_type(p, expected, actual); 723 } 724 725 int toy_type_accepts_type(ToyParser* p, ToyTypeId expected, ToyTypeId actual) { 726 const ToyType* exp = toy_type_get(p, expected); 727 const ToyType* act = toy_type_get(p, actual); 728 KitCgTypeId exp_cg, act_cg; 729 if (!exp || !act) return 0; 730 if (expected == actual) return 1; 731 if (exp->kind == TOY_TYPE_ALIAS || exp->kind == TOY_TYPE_QUALIFIED) 732 return toy_type_accepts_type(p, exp->base, actual); 733 if (act->kind == TOY_TYPE_ALIAS || act->kind == TOY_TYPE_QUALIFIED) 734 return toy_type_accepts_type(p, expected, act->base); 735 if (exp->kind == TOY_TYPE_PTR && act->kind == TOY_TYPE_PTR) { 736 return toy_type_accepts_storage_type(p, expected, actual); 737 } 738 if (exp->kind == TOY_TYPE_ARRAY && act->kind == TOY_TYPE_ARRAY) { 739 return toy_type_accepts_storage_type(p, expected, actual); 740 } 741 if (exp->kind == TOY_TYPE_SLICE && act->kind == TOY_TYPE_SLICE) 742 return toy_type_accepts_storage_type(p, expected, actual); 743 if (exp->kind == TOY_TYPE_FUNC && act->kind == TOY_TYPE_FUNC) { 744 return toy_type_accepts_storage_type(p, expected, actual); 745 } 746 if (exp->kind == TOY_TYPE_ANON_RECORD && act->kind == TOY_TYPE_ANON_RECORD) 747 return toy_anon_record_types_match(p, exp->cg, act->cg); 748 exp_cg = toy_type_resolved_cg(p, expected); 749 act_cg = toy_type_resolved_cg(p, actual); 750 if (exp_cg != KIT_CG_TYPE_NONE && act_cg != KIT_CG_TYPE_NONE) { 751 KitCgTypeKind exp_kind = kit_cg_type_kind(p->c, exp_cg); 752 KitCgTypeKind act_kind = kit_cg_type_kind(p->c, act_cg); 753 if (exp_kind == KIT_CG_TYPE_INT && act_kind == KIT_CG_TYPE_INT && 754 toy_type_int_width(p, act_cg) <= toy_type_int_width(p, exp_cg)) { 755 return 1; 756 } 757 if (exp_kind == KIT_CG_TYPE_FLOAT && act_kind == KIT_CG_TYPE_FLOAT && 758 kit_cg_type_float_width(p->c, act_cg) <= 759 kit_cg_type_float_width(p->c, exp_cg)) { 760 return 1; 761 } 762 } 763 return exp_cg != KIT_CG_TYPE_NONE && exp_cg == act_cg && 764 exp->kind != TOY_TYPE_NOMINAL_RECORD && 765 exp->kind != TOY_TYPE_TUPLE_RECORD && exp->kind != TOY_TYPE_ENUM; 766 } 767 768 int toy_record_field_index(ToyParser* p, KitCgTypeId record_ty, 769 KitSym field_name, uint32_t* index_out, 770 KitCgFieldLayout* field_out) { 771 const KitCgRecordLayout* L = kit_cg_type_record_layout(p->c, record_ty); 772 uint32_t i; 773 if (!L) return 0; 774 for (i = 0; i < L->nfields; ++i) { 775 if (L->fields[i].name == field_name) { 776 if (index_out) *index_out = i; 777 if (field_out) *field_out = L->fields[i]; 778 return 1; 779 } 780 } 781 return 0; 782 } 783 784 ToyNamedType* toy_find_named_type(ToyParser* p, KitSym name) { 785 size_t i; 786 for (i = p->module->type_table.count; i > 0; --i) { 787 if (p->module->type_table.named[i - 1].name == name) 788 return &p->module->type_table.named[i - 1]; 789 } 790 return NULL; 791 } 792 793 ToyNamedType* toy_find_named_type_by_type(ToyParser* p, KitCgTypeId type) { 794 size_t i; 795 for (i = p->module->type_table.count; i > 0; --i) { 796 if (p->module->type_table.named[i - 1].type == type) 797 return &p->module->type_table.named[i - 1]; 798 } 799 return NULL; 800 } 801 802 int toy_add_named_type(ToyParser* p, KitSym name, KitCgTypeId type, 803 ToyNamedTypeKind kind, KitCgTypeId base_type) { 804 ToyNamedType* existing = toy_find_named_type(p, name); 805 ToyTypeId toy_type = TOY_TYPE_NONE; 806 if (kind == TOY_NAMED_ALIAS) 807 toy_type = toy_type_register_alias(p, name, type, base_type); 808 else if (kind == TOY_NAMED_ENUM) 809 toy_type = toy_type_register_enum(p, name, type, base_type); 810 else 811 toy_type = 812 toy_type_register_named_record(p, name, type, kind == TOY_NAMED_TUPLE); 813 if (toy_type == TOY_TYPE_NONE && type != KIT_CG_TYPE_NONE) return 0; 814 if (existing && existing->type == KIT_CG_TYPE_NONE) { 815 /* Completing a forward declaration mutates an existing entry in place; if 816 * it was committed before this compile, snapshot it for rollback. */ 817 if (!toy_txn_record_named( 818 p, (size_t)(existing - p->module->type_table.named))) { 819 return 0; 820 } 821 existing->type = type; 822 existing->toy_type = toy_type; 823 existing->kind = kind; 824 existing->base_type = base_type; 825 return 1; 826 } 827 if (!toy_parser_reserve(p, (void**)&p->module->type_table.named, 828 &p->module->type_table.cap, 829 p->module->type_table.count + 1u, 830 sizeof *p->module->type_table.named, "named types")) { 831 return 0; 832 } 833 memset(&p->module->type_table.named[p->module->type_table.count], 0, 834 sizeof p->module->type_table.named[p->module->type_table.count]); 835 p->module->type_table.named[p->module->type_table.count].name = name; 836 p->module->type_table.named[p->module->type_table.count].type = type; 837 p->module->type_table.named[p->module->type_table.count].toy_type = toy_type; 838 p->module->type_table.named[p->module->type_table.count].kind = kind; 839 p->module->type_table.named[p->module->type_table.count].base_type = 840 base_type; 841 p->module->type_table.count++; 842 return 1; 843 } 844 845 int toy_set_named_type_fields(ToyParser* p, ToyNamedType* named, 846 const ToyRecordFieldInfo* fields, 847 size_t nfields) { 848 if (!toy_txn_record_named(p, (size_t)(named - p->module->type_table.named))) { 849 return 0; 850 } 851 if (!toy_parser_reserve(p, (void**)&named->fields, &named->cap_fields, 852 nfields, sizeof *named->fields, "record fields")) { 853 return 0; 854 } 855 if (nfields) memcpy(named->fields, fields, sizeof *named->fields * nfields); 856 named->nfields = nfields; 857 return 1; 858 } 859 860 int toy_set_named_type_enum_values(ToyParser* p, ToyNamedType* named, 861 const ToyEnumConst* values, size_t nvalues) { 862 if (!named) return 0; 863 if (!toy_txn_record_named(p, (size_t)(named - p->module->type_table.named))) { 864 return 0; 865 } 866 if (!toy_parser_reserve(p, (void**)&named->enum_values, 867 &named->cap_enum_values, nvalues, 868 sizeof *named->enum_values, "enum values")) { 869 return 0; 870 } 871 if (nvalues) memcpy(named->enum_values, values, sizeof values[0] * nvalues); 872 named->nenum_values = nvalues; 873 return 1; 874 }