kit

kit
git clone https://git.ryansepassi.com/git/kit.git
Log | Files | Refs | README

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**)&param_types, &cap_param_types,
    370                               nparams + 1u, sizeof *param_types,
    371                               "function parameter types") ||
    372           !toy_parser_reserve(p, (void**)&param_attrs, &cap_param_attrs,
    373                               nparams + 1u, sizeof *param_attrs,
    374                               "function parameter attrs") ||
    375           !toy_parser_reserve(p, (void**)&param_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**)&param_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, &param_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 }