kit

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

symbols.c (9629B)


      1 #include "internal.h"
      2 
      3 ToyVar* toy_find_var(ToyParser* p, KitSym name) {
      4   size_t i;
      5   for (i = p->nvars; i > 0; --i) {
      6     if (p->vars[i - 1].name == name) return &p->vars[i - 1];
      7   }
      8   return NULL;
      9 }
     10 
     11 int toy_add_local_typed(ToyParser* p, KitSym name, KitCgTypeId ty,
     12                         ToyTypeId toy_type, KitCgLocal slot, int mutable) {
     13   if (!toy_parser_reserve(p, (void**)&p->vars, &p->cap_vars, p->nvars + 1u,
     14                           sizeof *p->vars, "locals")) {
     15     return 0;
     16   }
     17   p->vars[p->nvars].name = name;
     18   p->vars[p->nvars].type = ty;
     19   p->vars[p->nvars].toy_type =
     20       toy_type != TOY_TYPE_NONE ? toy_type : toy_type_from_cg(p, ty);
     21   p->vars[p->nvars].local = slot;
     22   p->vars[p->nvars].static_sym = KIT_CG_SYM_NONE;
     23   p->vars[p->nvars].is_static = 0;
     24   p->vars[p->nvars].mutable = mutable;
     25   p->nvars++;
     26   return 1;
     27 }
     28 
     29 int toy_add_static_local_typed(ToyParser* p, KitSym name, KitCgTypeId ty,
     30                                ToyTypeId toy_type, KitCgSym sym, int mutable) {
     31   if (!toy_parser_reserve(p, (void**)&p->vars, &p->cap_vars, p->nvars + 1u,
     32                           sizeof *p->vars, "locals")) {
     33     return 0;
     34   }
     35   p->vars[p->nvars].name = name;
     36   p->vars[p->nvars].type = ty;
     37   p->vars[p->nvars].toy_type =
     38       toy_type != TOY_TYPE_NONE ? toy_type : toy_type_from_cg(p, ty);
     39   p->vars[p->nvars].local = KIT_CG_LOCAL_NONE;
     40   p->vars[p->nvars].static_sym = sym;
     41   p->vars[p->nvars].is_static = 1;
     42   p->vars[p->nvars].mutable = mutable;
     43   p->nvars++;
     44   return 1;
     45 }
     46 
     47 ToyFn* toy_find_fn(ToyParser* p, KitSym name) {
     48   size_t i;
     49   for (i = p->module->nfns; i > 0; --i) {
     50     if (p->module->fns[i - 1].name == name) return &p->module->fns[i - 1];
     51   }
     52   return NULL;
     53 }
     54 
     55 ToyFn* toy_add_fn_typed(ToyParser* p, KitSym name, KitCgSym sym,
     56                         KitCgTypeId type, ToyTypeId toy_type, KitCgTypeId ret,
     57                         ToyTypeId toy_ret, const KitCgTypeId* params,
     58                         const ToyTypeId* toy_params, size_t nparams,
     59                         int variadic) {
     60   ToyFn* fn;
     61   size_t i;
     62   if (!toy_parser_reserve(p, (void**)&p->module->fns, &p->module->cap_fns,
     63                           p->module->nfns + 1u, sizeof *p->module->fns,
     64                           "functions")) {
     65     return NULL;
     66   }
     67   /* Record the current-object symbol for this index before touching the slot,
     68    * so an OOM here leaves nothing half-added (nfns is bumped only at the end).
     69    */
     70   if (!toy_fn_set_cur_sym(p, p->module->nfns, sym)) return NULL;
     71   fn = &p->module->fns[p->module->nfns];
     72   fn->params = NULL;
     73   fn->toy_params = NULL;
     74   if (nparams != 0) {
     75     fn->params = (KitCgTypeId*)toy_parser_zalloc(p, nparams, sizeof *fn->params,
     76                                                  "function parameters");
     77     fn->toy_params = (ToyTypeId*)toy_parser_zalloc(
     78         p, nparams, sizeof *fn->toy_params, "function parameters");
     79     if (!fn->params || !fn->toy_params) {
     80       toy_parser_free_mem(p, fn->params, nparams * sizeof *fn->params);
     81       toy_parser_free_mem(p, fn->toy_params, nparams * sizeof *fn->toy_params);
     82       fn->params = NULL;
     83       fn->toy_params = NULL;
     84       return NULL;
     85     }
     86   }
     87   fn->name = name;
     88   fn->type = type;
     89   fn->toy_type =
     90       toy_type != TOY_TYPE_NONE ? toy_type : toy_type_from_cg(p, type);
     91   fn->ret = ret;
     92   fn->toy_ret = toy_ret != TOY_TYPE_NONE ? toy_ret : toy_type_from_cg(p, ret);
     93   fn->nparams = nparams;
     94   fn->variadic = variadic;
     95   for (i = 0; i < nparams; ++i) {
     96     fn->params[i] = params[i];
     97     fn->toy_params[i] = (toy_params && toy_params[i] != TOY_TYPE_NONE)
     98                             ? toy_params[i]
     99                             : toy_type_from_cg(p, params[i]);
    100   }
    101   p->module->nfns++;
    102   return fn;
    103 }
    104 
    105 ToyGlobal* toy_find_global(ToyParser* p, KitSym name) {
    106   size_t i;
    107   for (i = p->module->nglobals; i > 0; --i) {
    108     if (p->module->globals[i - 1].name == name)
    109       return &p->module->globals[i - 1];
    110   }
    111   return NULL;
    112 }
    113 
    114 int toy_add_global_typed(ToyParser* p, KitSym name, KitCgSym sym,
    115                          KitCgTypeId type, ToyTypeId toy_type, int mutable) {
    116   if (!toy_parser_reserve(p, (void**)&p->module->globals,
    117                           &p->module->cap_globals, p->module->nglobals + 1u,
    118                           sizeof *p->module->globals, "globals")) {
    119     return 0;
    120   }
    121   if (!toy_global_set_cur_sym(p, p->module->nglobals, sym)) return 0;
    122   p->module->globals[p->module->nglobals].name = name;
    123   p->module->globals[p->module->nglobals].type = type;
    124   p->module->globals[p->module->nglobals].toy_type =
    125       toy_type != TOY_TYPE_NONE ? toy_type : toy_type_from_cg(p, type);
    126   p->module->globals[p->module->nglobals].mutable = mutable;
    127   p->module->nglobals++;
    128   return 1;
    129 }
    130 
    131 ToyLabel* toy_find_label(ToyParser* p, KitSym name) {
    132   size_t i;
    133   for (i = p->nlabels; i > 0; --i) {
    134     if (p->labels[i - 1].name == name) return &p->labels[i - 1];
    135   }
    136   return NULL;
    137 }
    138 
    139 ToyLabel* toy_declare_label(ToyParser* p, KitSym name) {
    140   ToyLabel* existing = toy_find_label(p, name);
    141   if (existing) return existing;
    142   if (!toy_parser_reserve(p, (void**)&p->labels, &p->cap_labels,
    143                           p->nlabels + 1u, sizeof *p->labels, "labels"))
    144     return NULL;
    145   p->labels[p->nlabels].name = name;
    146   p->labels[p->nlabels].label = kit_cg_label_new(p->cg);
    147   return &p->labels[p->nlabels++];
    148 }
    149 
    150 ToyScope* toy_find_scope(ToyParser* p, KitSym name) {
    151   size_t i;
    152   if (p->nscopes == 0) return NULL;
    153   if (!name) return &p->scopes[p->nscopes - 1];
    154   for (i = p->nscopes; i > 0; --i) {
    155     if (p->scopes[i - 1].name == name) return &p->scopes[i - 1];
    156   }
    157   return NULL;
    158 }
    159 
    160 ToyScope* toy_find_innermost_loop_scope(ToyParser* p) {
    161   size_t i;
    162   for (i = p->nscopes; i > 0; --i) {
    163     if (p->scopes[i - 1].kind == TOY_SCOPE_LOOP) return &p->scopes[i - 1];
    164   }
    165   return NULL;
    166 }
    167 
    168 /* Pushes the variable's address as a pointer VALUE for the chained-memop
    169  * paths: a frame-local yields `push_local_addr`, a static-local yields its
    170  * symbol address. Callers turn the pointer into a PLACE with `kit_cg_deref`
    171  * (offset 0 for the whole object) before a load/store, and compose field /
    172  * index selectors on the pointer with the address-chain helpers. This keeps a
    173  * single uniform shape (pointer VALUE) regardless of storage class, matching
    174  * the `push_symbol_addr` shape used for globals. */
    175 void toy_push_var_lvalue(ToyParser* p, const ToyVar* v) {
    176   if (v->is_static)
    177     kit_cg_push_symbol_addr(p->cg, v->static_sym, 0);
    178   else
    179     kit_cg_push_local_addr(p->cg, v->local);
    180 }
    181 
    182 void toy_push_var_addr(ToyParser* p, const ToyVar* v) {
    183   if (v->is_static)
    184     kit_cg_push_symbol_addr(p->cg, v->static_sym, 0);
    185   else
    186     kit_cg_push_local_addr(p->cg, v->local);
    187 }
    188 
    189 /* Address-chain helpers for the chained-lvalue paths in the toy frontend.
    190  *
    191  * The canonical CG memops carry only a single effective address. Field and
    192  * index selectors that immediately precede a load/store therefore fold into
    193  * the memop's `ea` directly. When the toy parser builds a multi-step chain
    194  * (e.g. `&a.f[i].g`), each intermediate step must materialize the address
    195  * with explicit pointer arithmetic so the next step sees a pointer rvalue
    196  * it can compose with again. These helpers do that materialization.
    197  *
    198  * Inputs are pointer rvalues; outputs are pointer rvalues. Chain starts
    199  * push the root pointer via `kit_cg_push_local_addr` or
    200  * `kit_cg_push_symbol_addr` (or `kit_cg_addr` after `push_local`). */
    201 
    202 /* TOS: [base_ptr].  After: [base_ptr + offset] as `result_ptr_ty`. */
    203 void toy_addr_offset(ToyParser* p, int64_t offset, KitCgTypeId result_ptr_ty) {
    204   if (offset != 0) {
    205     kit_cg_ptr_to_int(p->cg, p->size_type);
    206     kit_cg_push_int(p->cg, (uint64_t)offset, p->size_type);
    207     kit_cg_int_binop(p->cg, KIT_CG_INT_ADD, 0);
    208     kit_cg_int_to_ptr(p->cg, result_ptr_ty);
    209   } else {
    210     kit_cg_bitcast(p->cg, result_ptr_ty);
    211   }
    212 }
    213 
    214 /* TOS: [base_ptr, index].
    215  * After: [base_ptr + index * elem_size] as `result_ptr_ty`. */
    216 void toy_addr_index(ToyParser* p, uint64_t elem_size,
    217                     KitCgTypeId result_ptr_ty) {
    218   kit_cg_push_int(p->cg, elem_size, p->size_type);
    219   kit_cg_int_binop(p->cg, KIT_CG_INT_MUL, 0);
    220   kit_cg_swap(p->cg);
    221   kit_cg_ptr_to_int(p->cg, p->size_type);
    222   kit_cg_int_binop(p->cg, KIT_CG_INT_ADD, 0);
    223   kit_cg_int_to_ptr(p->cg, result_ptr_ty);
    224 }
    225 
    226 KitCgSym toy_find_decl_sym(ToyParser* p, KitSym name) {
    227   ToyGlobal* g = toy_find_global(p, name);
    228   if (g) return toy_global_cur_sym(p, g);
    229   {
    230     ToyFn* fn = toy_find_fn(p, name);
    231     if (fn) return toy_fn_cur_sym(p, fn);
    232   }
    233   return KIT_CG_SYM_NONE;
    234 }
    235 
    236 KitCgSym toy_fn_cur_sym(ToyParser* p, const ToyFn* fn) {
    237   size_t index;
    238   if (!fn) return KIT_CG_SYM_NONE;
    239   index = (size_t)(fn - p->module->fns);
    240   if (index >= p->module->nfns) return KIT_CG_SYM_NONE;
    241   return p->fn_syms[index];
    242 }
    243 
    244 KitCgSym toy_global_cur_sym(ToyParser* p, const ToyGlobal* g) {
    245   size_t index;
    246   if (!g) return KIT_CG_SYM_NONE;
    247   index = (size_t)(g - p->module->globals);
    248   if (index >= p->module->nglobals) return KIT_CG_SYM_NONE;
    249   return p->global_syms[index];
    250 }
    251 
    252 int toy_fn_set_cur_sym(ToyParser* p, size_t index, KitCgSym sym) {
    253   if (!toy_parser_reserve(p, (void**)&p->fn_syms, &p->cap_fn_syms, index + 1u,
    254                           sizeof *p->fn_syms, "fn symbol env")) {
    255     return 0;
    256   }
    257   p->fn_syms[index] = sym;
    258   return 1;
    259 }
    260 
    261 int toy_global_set_cur_sym(ToyParser* p, size_t index, KitCgSym sym) {
    262   if (!toy_parser_reserve(p, (void**)&p->global_syms, &p->cap_global_syms,
    263                           index + 1u, sizeof *p->global_syms,
    264                           "global symbol env")) {
    265     return 0;
    266   }
    267   p->global_syms[index] = sym;
    268   return 1;
    269 }