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