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