decls.c (18357B)
1 #include <stdio.h> 2 #include <string.h> 3 4 #include "internal.h" 5 6 int toy_parse_type_alias_decl(ToyParser* p) { 7 KitSym name; 8 KitCgTypeId base; 9 if (!toy_parser_match(p, TOK_TYPE)) return 0; 10 if (p->cur.kind != TOK_IDENT) { 11 toy_error(p, p->cur.loc, "expected type alias name"); 12 return 0; 13 } 14 name = toy_tok_sym(p, p->cur); 15 toy_parser_advance(p); 16 if (!toy_parser_expect(p, TOK_EQ)) { 17 toy_error(p, p->cur.loc, "expected '=' in type alias"); 18 return 0; 19 } 20 base = toy_parse_type(p); 21 if (base == KIT_CG_TYPE_NONE) return 0; 22 if (!toy_parser_expect(p, TOK_SEMI)) { 23 toy_error(p, p->cur.loc, "expected ';' after type alias"); 24 return 0; 25 } 26 return toy_add_named_type(p, name, base, TOY_NAMED_ALIAS, base); 27 } 28 29 int toy_parse_record_decl(ToyParser* p) { 30 KitSym name; 31 KitCgFieldDesc* fields = NULL; 32 ToyRecordFieldInfo* field_infos = NULL; 33 size_t nfields = 0; 34 size_t cap_fields = 0; 35 size_t cap_field_infos = 0; 36 KitCgTypeId type = KIT_CG_TYPE_NONE; 37 ToyNamedType* named; 38 int packed = 0; 39 uint32_t record_align = 0; 40 int ok = 0; 41 42 if (!toy_parser_match(p, TOK_RECORD)) return 0; 43 if (!toy_parse_record_attr_list(p, &packed, &record_align)) return 0; 44 if (p->cur.kind != TOK_IDENT) { 45 toy_error(p, p->cur.loc, "expected record name"); 46 return 0; 47 } 48 name = toy_tok_sym(p, p->cur); 49 toy_parser_advance(p); 50 named = toy_find_named_type(p, name); 51 if (toy_parser_match(p, TOK_SEMI)) { 52 if (named) return 1; 53 type = kit_cg_type_record_decl(p->c, name, 0); 54 if (type == KIT_CG_TYPE_NONE) { 55 toy_error(p, p->cur.loc, "failed to declare record type"); 56 return 0; 57 } 58 return toy_add_named_type(p, name, type, TOY_NAMED_RECORD, type); 59 } 60 if (named) { 61 if (named->kind != TOY_NAMED_RECORD) { 62 toy_error(p, p->cur.loc, "record name already used for another type"); 63 return 0; 64 } 65 type = named->type; 66 if (type == KIT_CG_TYPE_NONE) { 67 type = kit_cg_type_record_decl(p->c, name, 0); 68 if (type == KIT_CG_TYPE_NONE || 69 !toy_add_named_type(p, name, type, TOY_NAMED_RECORD, type)) { 70 toy_error(p, p->cur.loc, "failed to declare record type"); 71 return 0; 72 } 73 named = toy_find_named_type(p, name); 74 } else if (kit_cg_type_is_complete(p->c, type)) { 75 toy_error(p, p->cur.loc, "record type redefinition"); 76 return 0; 77 } 78 } else { 79 type = kit_cg_type_record_decl(p->c, name, 0); 80 if (type == KIT_CG_TYPE_NONE || 81 !toy_add_named_type(p, name, type, TOY_NAMED_RECORD, type)) { 82 toy_error(p, p->cur.loc, "failed to declare record type"); 83 return 0; 84 } 85 named = toy_find_named_type(p, name); 86 } 87 if (!toy_parser_expect(p, TOK_LBRACE)) { 88 toy_error(p, p->cur.loc, "expected '{' after record name"); 89 return 0; 90 } 91 while (p->cur.kind != TOK_RBRACE && p->cur.kind != TOK_EOF) { 92 if (!toy_parser_reserve(p, (void**)&fields, &cap_fields, nfields + 1u, 93 sizeof *fields, "record fields") || 94 !toy_parser_reserve(p, (void**)&field_infos, &cap_field_infos, 95 nfields + 1u, sizeof *field_infos, 96 "record field info")) { 97 goto done; 98 } 99 if (p->cur.kind != TOK_IDENT) { 100 toy_error(p, p->cur.loc, "expected record field name"); 101 goto done; 102 } 103 fields[nfields].name = toy_tok_sym(p, p->cur); 104 toy_parser_advance(p); 105 if (!toy_parse_field_attr_list(p, &fields[nfields])) goto done; 106 if (!toy_parser_expect(p, TOK_COLON)) { 107 toy_error(p, p->cur.loc, "expected ':' after record field name"); 108 goto done; 109 } 110 fields[nfields].type = toy_parse_type(p); 111 if (fields[nfields].type == KIT_CG_TYPE_NONE) goto done; 112 field_infos[nfields].name = fields[nfields].name; 113 field_infos[nfields].storage_type = fields[nfields].type; 114 field_infos[nfields].toy_type = p->last_type; 115 nfields++; 116 if (!toy_parser_match(p, TOK_COMMA)) break; 117 } 118 if (!toy_parser_expect(p, TOK_RBRACE)) { 119 toy_error(p, p->cur.loc, "expected '}' after record declaration"); 120 goto done; 121 } 122 if (packed) { 123 size_t i; 124 for (i = 0; i < nfields; ++i) { 125 if (!fields[i].align_override) fields[i].align_override = 1; 126 } 127 } 128 if (!toy_cg_record_complete(p, type, name, fields, (uint32_t)nfields, 0, 129 record_align)) { 130 toy_error(p, p->cur.loc, "failed to create record type"); 131 goto done; 132 } 133 ok = named && toy_set_named_type_fields(p, named, field_infos, nfields); 134 135 done: 136 toy_parser_free_mem(p, fields, cap_fields * sizeof *fields); 137 toy_parser_free_mem(p, field_infos, cap_field_infos * sizeof *field_infos); 138 return ok; 139 } 140 141 int toy_parse_tuple_decl(ToyParser* p) { 142 KitSym name; 143 KitCgFieldDesc* fields = NULL; 144 ToyRecordFieldInfo* field_infos = NULL; 145 size_t nfields = 0; 146 size_t cap_fields = 0; 147 size_t cap_field_infos = 0; 148 KitCgTypeId type; 149 ToyNamedType* named; 150 char field_name_buf[16]; 151 int ok = 0; 152 153 if (!toy_parser_match(p, TOK_TUPLE)) return 0; 154 if (!toy_skip_attr_list(p)) return 0; 155 if (p->cur.kind != TOK_IDENT) { 156 toy_error(p, p->cur.loc, "expected tuple name"); 157 return 0; 158 } 159 name = toy_tok_sym(p, p->cur); 160 toy_parser_advance(p); 161 if (!toy_parser_expect(p, TOK_LBRACE)) { 162 toy_error(p, p->cur.loc, "expected '{' after tuple name"); 163 return 0; 164 } 165 while (p->cur.kind != TOK_RBRACE && p->cur.kind != TOK_EOF) { 166 if (!toy_parser_reserve(p, (void**)&fields, &cap_fields, nfields + 1u, 167 sizeof *fields, "tuple fields") || 168 !toy_parser_reserve(p, (void**)&field_infos, &cap_field_infos, 169 nfields + 1u, sizeof *field_infos, 170 "tuple field info")) { 171 goto done; 172 } 173 snprintf(field_name_buf, sizeof field_name_buf, "%u", (uint32_t)nfields); 174 fields[nfields].name = kit_sym_intern(p->c, kit_slice_cstr(field_name_buf)); 175 fields[nfields].type = toy_parse_type(p); 176 if (fields[nfields].type == KIT_CG_TYPE_NONE) goto done; 177 field_infos[nfields].name = fields[nfields].name; 178 field_infos[nfields].storage_type = fields[nfields].type; 179 field_infos[nfields].toy_type = p->last_type; 180 nfields++; 181 if (!toy_parser_match(p, TOK_COMMA)) break; 182 } 183 if (!toy_parser_expect(p, TOK_RBRACE)) { 184 toy_error(p, p->cur.loc, "expected '}' after tuple declaration"); 185 goto done; 186 } 187 type = toy_cg_record_type(p, name, fields, (uint32_t)nfields, 0, 0); 188 if (type == KIT_CG_TYPE_NONE) { 189 toy_error(p, p->cur.loc, "failed to create tuple type"); 190 goto done; 191 } 192 if (!toy_add_named_type(p, name, type, TOY_NAMED_TUPLE, type)) goto done; 193 named = toy_find_named_type(p, name); 194 ok = named && toy_set_named_type_fields(p, named, field_infos, nfields); 195 196 done: 197 toy_parser_free_mem(p, fields, cap_fields * sizeof *fields); 198 toy_parser_free_mem(p, field_infos, cap_field_infos * sizeof *field_infos); 199 return ok; 200 } 201 202 int toy_parse_enum_decl(ToyParser* p) { 203 KitSym name; 204 KitCgTypeId base; 205 KitCgEnumValue* values = NULL; 206 ToyEnumConst* toy_values = NULL; 207 size_t nvalues = 0; 208 size_t cap_values = 0; 209 size_t cap_toy_values = 0; 210 KitCgTypeId type; 211 ToyNamedType* named; 212 int ok = 0; 213 214 if (!toy_parser_match(p, TOK_ENUM)) return 0; 215 if (!toy_skip_attr_list(p)) return 0; 216 if (p->cur.kind != TOK_IDENT) { 217 toy_error(p, p->cur.loc, "expected enum name"); 218 return 0; 219 } 220 name = toy_tok_sym(p, p->cur); 221 toy_parser_advance(p); 222 if (!toy_parser_expect(p, TOK_COLON)) { 223 toy_error(p, p->cur.loc, "expected enum base type"); 224 return 0; 225 } 226 base = toy_parse_type(p); 227 if (base == KIT_CG_TYPE_NONE) return 0; 228 if (!toy_parser_expect(p, TOK_LBRACE)) { 229 toy_error(p, p->cur.loc, "expected '{' after enum base type"); 230 return 0; 231 } 232 while (p->cur.kind != TOK_RBRACE && p->cur.kind != TOK_EOF) { 233 if (!toy_parser_reserve(p, (void**)&values, &cap_values, nvalues + 1u, 234 sizeof *values, "enum values") || 235 !toy_parser_reserve(p, (void**)&toy_values, &cap_toy_values, 236 nvalues + 1u, sizeof *toy_values, 237 "toy enum values")) { 238 goto done; 239 } 240 if (!toy_parser_expect(p, TOK_DOT) || p->cur.kind != TOK_IDENT) { 241 toy_error(p, p->cur.loc, "expected enum value"); 242 goto done; 243 } 244 values[nvalues].name = toy_tok_sym(p, p->cur); 245 toy_values[nvalues].name = values[nvalues].name; 246 toy_parser_advance(p); 247 if (!toy_parser_expect(p, TOK_EQ) || p->cur.kind != TOK_NUMBER || 248 p->cur.is_float) { 249 toy_error(p, p->cur.loc, "expected enum integer value"); 250 goto done; 251 } 252 values[nvalues].value = p->cur.int_value; 253 toy_values[nvalues].value = p->cur.int_value; 254 toy_parser_advance(p); 255 nvalues++; 256 if (!toy_parser_match(p, TOK_COMMA)) break; 257 } 258 if (!toy_parser_expect(p, TOK_RBRACE)) { 259 toy_error(p, p->cur.loc, "expected '}' after enum declaration"); 260 goto done; 261 } 262 type = kit_cg_type_enum(p->c, name, base, values, (uint32_t)nvalues); 263 if (type == KIT_CG_TYPE_NONE) { 264 toy_error(p, p->cur.loc, "failed to create enum type"); 265 goto done; 266 } 267 if (!toy_add_named_type(p, name, type, TOY_NAMED_ENUM, base)) goto done; 268 named = toy_find_named_type(p, name); 269 ok = named && toy_set_named_type_enum_values(p, named, toy_values, nvalues); 270 271 done: 272 toy_parser_free_mem(p, values, cap_values * sizeof *values); 273 toy_parser_free_mem(p, toy_values, cap_toy_values * sizeof *toy_values); 274 return ok; 275 } 276 277 int toy_parse_alias_decl(ToyParser* p, int is_pub) { 278 KitSym name; 279 KitSym target_name; 280 KitCgSym target_sym; 281 KitCgAlias alias; 282 ToyAttrSet attrs; 283 KitSymBind default_bind = is_pub ? KIT_SB_GLOBAL : KIT_SB_LOCAL; 284 if (!toy_parser_match(p, TOK_ALIAS)) return 0; 285 if (!toy_parse_attr_list(p, &attrs, default_bind)) return 0; 286 if (!toy_validate_attr_placement(p, &attrs, TOY_ATTR_SYMBOL, 287 "invalid alias attribute")) 288 return 0; 289 if (p->cur.kind != TOK_IDENT) { 290 toy_error(p, p->cur.loc, "expected alias name"); 291 return 0; 292 } 293 name = toy_tok_sym(p, p->cur); 294 toy_parser_advance(p); 295 if (!toy_parser_expect(p, TOK_EQ) || p->cur.kind != TOK_IDENT) { 296 toy_error(p, p->cur.loc, "expected alias target"); 297 return 0; 298 } 299 target_name = toy_tok_sym(p, p->cur); 300 toy_parser_advance(p); 301 target_sym = toy_find_decl_sym(p, target_name); 302 if (target_sym == KIT_CG_SYM_NONE) { 303 toy_error(p, p->cur.loc, "undefined alias target"); 304 return 0; 305 } 306 memset(&alias, 0, sizeof alias); 307 alias.linkage_name = toy_c_linkage_name(p, name); 308 if (!alias.linkage_name) return 0; 309 alias.display_name = name; 310 alias.target = target_sym; 311 alias.sym = attrs.sym; 312 if (kit_cg_alias(p->cg, alias) == KIT_CG_SYM_NONE) { 313 toy_error(p, p->cur.loc, "failed to define alias"); 314 return 0; 315 } 316 if (!toy_parser_expect(p, TOK_SEMI)) { 317 toy_error(p, p->cur.loc, "expected ';' after alias"); 318 return 0; 319 } 320 return 1; 321 } 322 323 int toy_parse_fn(ToyParser* p, int is_extern, int is_pub) { 324 KitSym name; 325 KitCgTypeId ret_type; 326 KitCgTypeId* param_types = NULL; 327 ToyTypeId* param_toy_types = NULL; 328 KitCgAbiAttrs* param_attrs = NULL; 329 KitCgAbiAttrs ret_attrs; 330 KitCgFuncParam* sig_params = NULL; 331 KitSym* param_names = NULL; 332 size_t nparams = 0; 333 size_t cap_param_types = 0; 334 size_t cap_param_toy_types = 0; 335 size_t cap_param_attrs = 0; 336 size_t cap_sig_params = 0; 337 size_t cap_param_names = 0; 338 int variadic = 0; 339 KitCgDecl decl; 340 KitCgFuncSig sig; 341 KitCgTypeId fn_ty; 342 ToyFn* fn_entry; 343 ToyAttrSet attrs; 344 ToyTypeId fn_toy_type; 345 ToyTypeId ret_toy_type; 346 size_t i; 347 KitSymBind default_bind = 348 (is_extern || is_pub || 349 p->input_kind != KIT_FRONTEND_INPUT_TRANSLATION_UNIT) 350 ? KIT_SB_GLOBAL 351 : KIT_SB_LOCAL; 352 353 if (!toy_parser_match(p, TOK_FN)) return 0; 354 if (!toy_parse_attr_list(p, &attrs, default_bind)) return -1; 355 if (!toy_validate_attr_placement( 356 p, &attrs, TOY_ATTR_SYMBOL | TOY_ATTR_FUNC | TOY_ATTR_SECTION, 357 "invalid function attribute")) 358 return -1; 359 memset(&ret_attrs, 0, sizeof ret_attrs); 360 361 if (p->cur.kind != TOK_IDENT) { 362 toy_error(p, p->cur.loc, "expected function name"); 363 return -1; 364 } 365 name = toy_tok_sym(p, p->cur); 366 toy_parser_advance(p); 367 368 if (!toy_parser_expect(p, TOK_LPAREN)) { 369 toy_error(p, p->cur.loc, "expected '(' after function name"); 370 return -1; 371 } 372 373 if (p->cur.kind != TOK_RPAREN) { 374 for (;;) { 375 if (p->cur.kind == TOK_DOTDOTDOT) { 376 variadic = 1; 377 toy_parser_advance(p); 378 break; 379 } 380 if (p->cur.kind != TOK_IDENT) { 381 toy_error(p, p->cur.loc, "expected parameter name"); 382 return -1; 383 } 384 if (!toy_parser_reserve(p, (void**)¶m_types, &cap_param_types, 385 nparams + 1u, sizeof *param_types, 386 "function parameter types") || 387 !toy_parser_reserve(p, (void**)¶m_attrs, &cap_param_attrs, 388 nparams + 1u, sizeof *param_attrs, 389 "function parameter attrs") || 390 !toy_parser_reserve(p, (void**)¶m_toy_types, &cap_param_toy_types, 391 nparams + 1u, sizeof *param_toy_types, 392 "function parameter source types") || 393 !toy_parser_reserve(p, (void**)&sig_params, &cap_sig_params, 394 nparams + 1u, sizeof *sig_params, 395 "function signature parameters") || 396 !toy_parser_reserve(p, (void**)¶m_names, &cap_param_names, 397 nparams + 1u, sizeof *param_names, 398 "function parameter names")) { 399 return -1; 400 } 401 param_names[nparams] = toy_tok_sym(p, p->cur); 402 toy_parser_advance(p); 403 if (!toy_parse_abi_attr_list(p, ¶m_attrs[nparams])) return -1; 404 if (!toy_parser_expect(p, TOK_COLON)) { 405 toy_error(p, p->cur.loc, "expected ':' after parameter name"); 406 return -1; 407 } 408 param_types[nparams] = toy_parse_type(p); 409 if (param_types[nparams] == KIT_CG_TYPE_NONE) return -1; 410 param_toy_types[nparams] = p->last_type; 411 nparams++; 412 if (p->cur.kind == TOK_COMMA) { 413 toy_parser_advance(p); 414 if (p->cur.kind == TOK_DOTDOTDOT) { 415 variadic = 1; 416 toy_parser_advance(p); 417 break; 418 } 419 } else { 420 break; 421 } 422 } 423 } 424 if (!toy_parser_expect(p, TOK_RPAREN)) { 425 toy_error(p, p->cur.loc, "expected ')' after parameters"); 426 return -1; 427 } 428 429 if (toy_parser_match(p, TOK_COLON)) { 430 ret_type = toy_parse_type(p); 431 if (ret_type == KIT_CG_TYPE_NONE) return -1; 432 ret_toy_type = p->last_type; 433 if (!toy_parse_abi_attr_list(p, &ret_attrs)) return -1; 434 } else { 435 ret_type = toy_builtin_type(p, KIT_CG_BUILTIN_VOID); 436 ret_toy_type = toy_type_from_cg(p, ret_type); 437 } 438 439 for (i = 0; i < nparams; i++) { 440 sig_params[i].type = param_types[i]; 441 sig_params[i].attrs = param_attrs[i]; 442 } 443 memset(&sig, 0, sizeof sig); 444 sig.result.type = ret_type; 445 sig.result.attrs = ret_attrs; 446 sig.params = sig_params; 447 sig.nparams = (uint32_t)nparams; 448 sig.call_conv = attrs.has_call_conv ? attrs.call_conv : KIT_CG_CC_TARGET_C; 449 sig.abi_variadic = variadic; 450 451 fn_ty = kit_cg_type_func(p->c, sig); 452 if (fn_ty == KIT_CG_TYPE_NONE) { 453 toy_error(p, p->cur.loc, "failed to create function type"); 454 return -1; 455 } 456 fn_toy_type = toy_type_register_func(p, fn_ty, ret_toy_type, param_toy_types, 457 nparams, variadic); 458 459 memset(&decl, 0, sizeof(decl)); 460 decl.kind = KIT_CG_DECL_FUNC; 461 decl.linkage_name = toy_c_linkage_name(p, name); 462 if (!decl.linkage_name) return -1; 463 decl.display_name = name; 464 decl.type = fn_ty; 465 decl.sym = attrs.sym; 466 if (toy_sym_is(p, name, "main")) decl.sym.bind = KIT_SB_GLOBAL; 467 decl.as.func = attrs.func; 468 469 { 470 KitCgSym sym = kit_cg_decl(p->cg, decl); 471 if (sym == KIT_CG_SYM_NONE) { 472 toy_error(p, p->cur.loc, "failed to declare function"); 473 return -1; 474 } 475 fn_entry = toy_add_fn_typed(p, name, sym, fn_ty, fn_toy_type, ret_type, 476 ret_toy_type, param_types, param_toy_types, 477 nparams, variadic); 478 } 479 if (!fn_entry) { 480 toy_error(p, p->cur.loc, "failed to declare function"); 481 return -1; 482 } 483 fn_entry->sym_attrs = decl.sym; 484 fn_entry->func_attrs = decl.as.func; 485 486 if (is_extern) { 487 if (!toy_parser_expect(p, TOK_SEMI)) { 488 toy_error(p, p->cur.loc, "expected ';' after extern function"); 489 return -1; 490 } 491 toy_parser_free_mem(p, param_types, cap_param_types * sizeof *param_types); 492 toy_parser_free_mem(p, param_toy_types, 493 cap_param_toy_types * sizeof *param_toy_types); 494 toy_parser_free_mem(p, param_attrs, cap_param_attrs * sizeof *param_attrs); 495 toy_parser_free_mem(p, sig_params, cap_sig_params * sizeof *sig_params); 496 toy_parser_free_mem(p, param_names, cap_param_names * sizeof *param_names); 497 return 1; 498 } 499 500 kit_cg_func_begin_attrs(p->cg, toy_fn_cur_sym(p, fn_entry), 501 fn_entry->func_attrs); 502 503 p->nvars = 0; 504 p->nlabels = 0; 505 p->cur_fn_ret = ret_type; 506 p->cur_fn_ret_toy = ret_toy_type; 507 for (i = 0; i < nparams; i++) { 508 KitCgLocal param = kit_cg_param(p->cg, (uint32_t)i, param_types[i], 509 toy_slot_attrs(param_names[i])); 510 if (!toy_add_local_typed(p, param_names[i], param_types[i], 511 param_toy_types[i], param, 1)) 512 return -1; 513 } 514 515 if (!toy_parse_block(p)) return -1; 516 517 if (ret_type == toy_builtin_type(p, KIT_CG_BUILTIN_VOID)) { 518 kit_cg_ret(p->cg); 519 } 520 521 kit_cg_func_end(p->cg); 522 p->nvars = 0; 523 p->nlabels = 0; 524 p->cur_fn_ret = toy_builtin_type(p, KIT_CG_BUILTIN_VOID); 525 p->cur_fn_ret_toy = toy_type_from_cg(p, p->cur_fn_ret); 526 toy_parser_free_mem(p, param_types, cap_param_types * sizeof *param_types); 527 toy_parser_free_mem(p, param_toy_types, 528 cap_param_toy_types * sizeof *param_toy_types); 529 toy_parser_free_mem(p, param_attrs, cap_param_attrs * sizeof *param_attrs); 530 toy_parser_free_mem(p, sig_params, cap_sig_params * sizeof *sig_params); 531 toy_parser_free_mem(p, param_names, cap_param_names * sizeof *param_names); 532 return 1; 533 }