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 }