expr.c (64036B)
1 #include <stddef.h> 2 #include <stdint.h> 3 #include <stdio.h> 4 #include <string.h> 5 6 #include "internal.h" 7 8 /* Public CG API coverage goals for this frontend are tracked in 9 * doc/toy-todo.md. Keep this file aligned with include/kit/cg.h rather than 10 * private CG implementation details. */ 11 12 /* ============================================================ 13 * Parser (single-pass parse -> codegen) 14 * ============================================================ */ 15 16 /* ============================================================ 17 * Expression parsing 18 * ============================================================ */ 19 20 KitCgTypeId toy_parse_expr(ToyParser* p); 21 KitCgMemAccess toy_mem_access(ToyParser* p, KitCgTypeId type); 22 KitCgTypeId toy_emit_var_lvalue(ToyParser* p, KitSym name); 23 24 static void toy_note_cg_result_type(ToyParser* p, KitCgTypeId ty) { 25 p->last_type = toy_type_from_cg(p, ty); 26 } 27 28 static void toy_note_builtin_result_type(ToyParser* p, KitCgTypeId ty) { 29 KitCgTypeId last_cg = toy_type_resolved_cg(p, p->last_type); 30 if (last_cg != ty) toy_note_cg_result_type(p, ty); 31 } 32 33 static int toy_reject_tail_call_operand(ToyParser* p) { 34 if (!p->tail_call_expr) return 0; 35 toy_error(p, p->cur.loc, "tail @call must be returned directly"); 36 return 1; 37 } 38 39 KitCgTypeId toy_push_named_rvalue(ToyParser* p, KitSym name) { 40 ToyVar* v = toy_find_var(p, name); 41 if (v) { 42 if (kit_cg_type_kind(p->c, v->type) == KIT_CG_TYPE_RECORD) { 43 /* Record: leave the address (pointer VALUE) for the caller's copy. */ 44 toy_push_var_lvalue(p, v); 45 } else if (v->is_static) { 46 /* Static scalar: its address is a pointer; deref to a place, then load. 47 */ 48 kit_cg_push_symbol_addr(p->cg, v->static_sym, 0); 49 kit_cg_deref(p->cg, 0); 50 kit_cg_load(p->cg, toy_mem_access(p, v->type)); 51 } else { 52 /* Local scalar: the local's PLACE loads directly (no address round-trip, 53 * which keeps small accessors inlinable). */ 54 kit_cg_push_local(p->cg, v->local); 55 kit_cg_load(p->cg, toy_mem_access(p, v->type)); 56 } 57 p->last_type = v->toy_type; 58 return v->type; 59 } 60 { 61 ToyGlobal* g = toy_find_global(p, name); 62 if (g) { 63 kit_cg_push_symbol_addr(p->cg, toy_global_cur_sym(p, g), 0); 64 if (kit_cg_type_kind(p->c, g->type) != KIT_CG_TYPE_RECORD) { 65 kit_cg_deref(p->cg, 0); 66 kit_cg_load(p->cg, toy_mem_access(p, g->type)); 67 } 68 p->last_type = g->toy_type; 69 return g->type; 70 } 71 } 72 { 73 ToyFn* fn = toy_find_fn(p, name); 74 if (fn) { 75 KitCgTypeId ptr_ty = kit_cg_type_ptr(p->c, fn->type, 0); 76 kit_cg_push_symbol_addr(p->cg, toy_fn_cur_sym(p, fn), 0); 77 p->last_type = toy_type_register_ptr(p, ptr_ty, fn->toy_type, 0); 78 return ptr_ty; 79 } 80 } 81 return KIT_CG_TYPE_NONE; 82 } 83 84 int toy_parse_call_args(ToyParser* p, ToyToken call_tok, KitCgTypeId fn_ty, 85 const ToyTypeId* toy_params, size_t toy_nparams, 86 size_t* out_nargs) { 87 uint32_t nparams = kit_cg_type_func_nparams(p->c, fn_ty); 88 int variadic = kit_cg_type_func_is_variadic(p->c, fn_ty); 89 size_t nargs = 0; 90 if (p->cur.kind != TOK_RPAREN) { 91 for (;;) { 92 KitCgTypeId arg_ty; 93 if (nargs < nparams && p->cur.kind == TOK_DOT) { 94 KitCgFuncParam param = 95 kit_cg_type_func_param(p->c, fn_ty, (uint32_t)nargs); 96 ToyNamedType* named = toy_find_named_type_by_type(p, param.type); 97 KitSym value_name; 98 size_t i; 99 int found = 0; 100 int64_t value = 0; 101 toy_parser_advance(p); /* . */ 102 if (p->cur.kind != TOK_IDENT) { 103 toy_error(p, p->cur.loc, "expected enum value"); 104 return 0; 105 } 106 value_name = toy_tok_sym(p, p->cur); 107 toy_parser_advance(p); 108 if (!named || named->kind != TOY_NAMED_ENUM) { 109 toy_error(p, p->cur.loc, "dot argument requires enum parameter"); 110 return 0; 111 } 112 for (i = 0; i < named->nenum_values; ++i) { 113 if (named->enum_values[i].name == value_name) { 114 found = 1; 115 value = named->enum_values[i].value; 116 break; 117 } 118 } 119 if (!found) { 120 toy_error(p, p->cur.loc, "unknown enum value"); 121 return 0; 122 } 123 kit_cg_push_int(p->cg, (uint64_t)value, param.type); 124 arg_ty = param.type; 125 p->last_type = (toy_params && nargs < toy_nparams) 126 ? toy_params[nargs] 127 : toy_type_from_cg(p, arg_ty); 128 } else { 129 arg_ty = toy_parse_expr(p); 130 } 131 if (arg_ty == KIT_CG_TYPE_NONE) return 0; 132 if (toy_reject_tail_call_operand(p)) return 0; 133 if (nargs < nparams) { 134 KitCgFuncParam param = 135 kit_cg_type_func_param(p->c, fn_ty, (uint32_t)nargs); 136 ToyTypeId expected = (toy_params && nargs < toy_nparams) 137 ? toy_params[nargs] 138 : TOY_TYPE_NONE; 139 ToyTypeId actual = p->last_type; 140 if (expected != TOY_TYPE_NONE && 141 !toy_type_accepts_type(p, expected, actual)) { 142 toy_error(p, call_tok.loc, "function argument type mismatch"); 143 return 0; 144 } 145 if (expected == TOY_TYPE_NONE && 146 !toy_type_can_implicitly_cast(p, arg_ty, param.type)) { 147 toy_error(p, call_tok.loc, "function argument type mismatch"); 148 return 0; 149 } 150 if (arg_ty != param.type) { 151 if (expected != TOY_TYPE_NONE) { 152 if (!toy_emit_checked_cast(p, arg_ty, param.type)) return 0; 153 } else if (!toy_emit_implicit_cast(p, arg_ty, param.type)) { 154 return 0; 155 } 156 } 157 } else if (!variadic) { 158 toy_error(p, call_tok.loc, "too many arguments"); 159 return 0; 160 } 161 nargs++; 162 if (!toy_parser_match(p, TOK_COMMA)) break; 163 } 164 } 165 if (!toy_parser_expect(p, TOK_RPAREN)) { 166 toy_error(p, p->cur.loc, "expected ')' after arguments"); 167 return 0; 168 } 169 if (nargs < nparams) { 170 toy_error(p, call_tok.loc, "too few arguments"); 171 return 0; 172 } 173 *out_nargs = nargs; 174 return 1; 175 } 176 177 KitCgMemAccess toy_mem_access(ToyParser* p, KitCgTypeId type) { 178 KitCgMemAccess access; 179 (void)p; 180 memset(&access, 0, sizeof access); 181 access.type = type; 182 return access; 183 } 184 185 static int toy_type_is_promotable_int(ToyParser* p, KitCgTypeId ty) { 186 return kit_cg_type_kind(p->c, ty) == KIT_CG_TYPE_INT; 187 } 188 189 static KitCgTypeId toy_int_literal_type(ToyParser* p, int64_t value) { 190 if (value <= INT8_MAX) return toy_builtin_type(p, KIT_CG_BUILTIN_I8); 191 if (value <= INT16_MAX) return toy_builtin_type(p, KIT_CG_BUILTIN_I16); 192 if (value <= INT32_MAX) return toy_builtin_type(p, KIT_CG_BUILTIN_I32); 193 return toy_builtin_type(p, KIT_CG_BUILTIN_I64); 194 } 195 196 int toy_type_can_implicitly_cast(ToyParser* p, KitCgTypeId src, 197 KitCgTypeId dst) { 198 KitCgTypeKind sk, dk; 199 if (src == dst) return 1; 200 sk = kit_cg_type_kind(p->c, src); 201 dk = kit_cg_type_kind(p->c, dst); 202 if (sk == KIT_CG_TYPE_INT && dk == KIT_CG_TYPE_INT) 203 return toy_type_int_width(p, src) <= toy_type_int_width(p, dst); 204 if (sk == KIT_CG_TYPE_FLOAT && dk == KIT_CG_TYPE_FLOAT) 205 return kit_cg_type_float_width(p->c, src) <= 206 kit_cg_type_float_width(p->c, dst); 207 return 0; 208 } 209 210 int toy_emit_cast(ToyParser* p, KitCgTypeId src, KitCgTypeId dst) { 211 KitCgTypeKind sk, dk; 212 if (src == dst) return 1; 213 sk = kit_cg_type_kind(p->c, src); 214 dk = kit_cg_type_kind(p->c, dst); 215 216 if (dk == KIT_CG_TYPE_BOOL && toy_type_is_intlike(p, src)) { 217 kit_cg_push_int(p->cg, 0, src); 218 kit_cg_int_cmp(p->cg, KIT_CG_INT_NE); 219 return 1; 220 } 221 if (toy_type_is_intlike(p, src) && toy_type_is_intlike(p, dst)) { 222 uint32_t sw = toy_type_int_width(p, src); 223 uint32_t dw = toy_type_int_width(p, dst); 224 if (dw > sw && sk == KIT_CG_TYPE_BOOL) 225 kit_cg_zext(p->cg, dst); 226 else if (dw > sw) 227 kit_cg_sext(p->cg, dst); 228 else if (dw < sw) 229 kit_cg_trunc(p->cg, dst); 230 return 1; 231 } 232 if (toy_type_is_intlike(p, src) && dk == KIT_CG_TYPE_FLOAT) { 233 kit_cg_sint_to_float(p->cg, dst, KIT_CG_ROUND_DEFAULT); 234 return 1; 235 } 236 if (sk == KIT_CG_TYPE_FLOAT && toy_type_is_intlike(p, dst)) { 237 kit_cg_float_to_sint(p->cg, dst, KIT_CG_ROUND_TOWARD_ZERO); 238 return 1; 239 } 240 if (sk == KIT_CG_TYPE_FLOAT && dk == KIT_CG_TYPE_FLOAT) { 241 uint32_t sw = kit_cg_type_float_width(p->c, src); 242 uint32_t dw = kit_cg_type_float_width(p->c, dst); 243 if (dw > sw) 244 kit_cg_fpext(p->cg, dst); 245 else if (dw < sw) 246 kit_cg_fptrunc(p->cg, dst); 247 return 1; 248 } 249 if (sk == KIT_CG_TYPE_PTR && toy_type_is_intlike(p, dst)) { 250 kit_cg_ptr_to_int(p->cg, dst); 251 return 1; 252 } 253 if (toy_type_is_intlike(p, src) && dk == KIT_CG_TYPE_PTR) { 254 kit_cg_int_to_ptr(p->cg, dst); 255 return 1; 256 } 257 if (sk == KIT_CG_TYPE_PTR && dk == KIT_CG_TYPE_PTR) { 258 kit_cg_bitcast(p->cg, dst); 259 return 1; 260 } 261 toy_error(p, p->cur.loc, "unsupported cast"); 262 return 0; 263 } 264 265 int toy_emit_implicit_cast(ToyParser* p, KitCgTypeId src, KitCgTypeId dst) { 266 if (src == dst) return 1; 267 if (!toy_type_can_implicitly_cast(p, src, dst)) { 268 toy_error(p, p->cur.loc, "implicit conversion would lose information"); 269 return 0; 270 } 271 return toy_emit_cast(p, src, dst); 272 } 273 274 int toy_emit_checked_cast(ToyParser* p, KitCgTypeId src, KitCgTypeId dst) { 275 KitCgTypeKind sk, dk; 276 if (src == dst) return 1; 277 if (toy_type_can_implicitly_cast(p, src, dst)) 278 return toy_emit_cast(p, src, dst); 279 sk = kit_cg_type_kind(p->c, src); 280 dk = kit_cg_type_kind(p->c, dst); 281 if (sk == KIT_CG_TYPE_PTR && dk == KIT_CG_TYPE_PTR) { 282 kit_cg_bitcast(p->cg, dst); 283 return 1; 284 } 285 toy_error(p, p->cur.loc, "unsupported checked conversion"); 286 return 0; 287 } 288 289 static int toy_promote_right_operand(ToyParser* p, KitCgTypeId src, 290 KitCgTypeId dst) { 291 return toy_emit_implicit_cast(p, src, dst); 292 } 293 294 static int toy_promote_left_operand(ToyParser* p, KitCgTypeId src, 295 KitCgTypeId dst) { 296 kit_cg_swap(p->cg); 297 if (!toy_emit_implicit_cast(p, src, dst)) return 0; 298 kit_cg_swap(p->cg); 299 return 1; 300 } 301 302 static int toy_promote_binary_int_operands(ToyParser* p, KitCgTypeId* left, 303 KitCgTypeId* right) { 304 uint32_t lw, rw; 305 if (*left == *right) return 1; 306 if (!toy_type_is_promotable_int(p, *left) || 307 !toy_type_is_promotable_int(p, *right)) 308 return 0; 309 lw = toy_type_int_width(p, *left); 310 rw = toy_type_int_width(p, *right); 311 if (lw < rw) { 312 if (!toy_promote_left_operand(p, *left, *right)) return 0; 313 *left = *right; 314 } else if (rw < lw) { 315 if (!toy_promote_right_operand(p, *right, *left)) return 0; 316 *right = *left; 317 } else { 318 return 0; 319 } 320 return 1; 321 } 322 323 KitCgLocalAttrs toy_slot_attrs(KitSym name) { 324 KitCgLocalAttrs attrs; 325 memset(&attrs, 0, sizeof attrs); 326 attrs.name = name; 327 return attrs; 328 } 329 330 KitSym toy_c_linkage_name(ToyParser* p, KitSym source_name) { 331 KitSym linkage_name = kit_cg_c_linkage_name(p->c, source_name); 332 if (!linkage_name) { 333 toy_error(p, p->cur.loc, "failed to create linkage name"); 334 } 335 return linkage_name; 336 } 337 338 void toy_inline_asm(ToyParser* p, KitSym tmpl, const KitCgAsmOperand* outputs, 339 uint32_t noutputs, const KitCgAsmOperand* inputs, 340 uint32_t ninputs, const KitSym* clobbers, 341 uint32_t nclobbers, uint32_t flags, 342 uint32_t clobber_abi_sets) { 343 KitCgInlineAsm asm_block; 344 memset(&asm_block, 0, sizeof asm_block); 345 asm_block.tmpl = tmpl; 346 asm_block.outputs = outputs; 347 asm_block.noutputs = noutputs; 348 asm_block.inputs = inputs; 349 asm_block.ninputs = ninputs; 350 asm_block.clobbers = clobbers; 351 asm_block.nclobbers = nclobbers; 352 asm_block.flags = flags; 353 asm_block.clobber_abi_sets = clobber_abi_sets; 354 kit_cg_inline_asm(p->cg, asm_block); 355 } 356 357 int toy_emit_truthy(ToyParser* p, KitCgTypeId type) { 358 if (type == toy_builtin_type(p, KIT_CG_BUILTIN_BOOL)) return 1; 359 if (toy_type_is_intlike(p, type)) { 360 kit_cg_push_int(p->cg, 0, type); 361 kit_cg_int_cmp(p->cg, KIT_CG_INT_NE); 362 return 1; 363 } 364 toy_error(p, p->cur.loc, "condition must be int or bool"); 365 return 0; 366 } 367 368 static int toy_note_expr_island(ToyParser* p, ToyExprIsland island) { 369 uint32_t prior = p->expr_island_mask; 370 if (prior && prior != (uint32_t)island) { 371 toy_error(p, p->cur.loc, "mixed precedence islands require parentheses"); 372 return 0; 373 } 374 p->expr_island_mask |= (uint32_t)island; 375 return 1; 376 } 377 378 int toy_expect_comma(ToyParser* p) { 379 if (!toy_parser_expect(p, TOK_COMMA)) { 380 toy_error(p, p->cur.loc, "expected ','"); 381 return 0; 382 } 383 return 1; 384 } 385 386 static int toy_parse_dot_constant_value(ToyParser* p, int64_t* out) { 387 KitSym name; 388 if (!toy_parser_expect(p, TOK_DOT) || p->cur.kind != TOK_IDENT) { 389 toy_error(p, p->cur.loc, "expected dot constant"); 390 return 0; 391 } 392 name = toy_tok_sym(p, p->cur); 393 toy_parser_advance(p); 394 if (toy_sym_is(p, name, "arm64")) 395 *out = 1; 396 else if (toy_sym_is(p, name, "x64")) 397 *out = 2; 398 else if (toy_sym_is(p, name, "rv64")) 399 *out = 3; 400 else if (toy_sym_is(p, name, "x86")) 401 *out = 4; 402 else if (toy_sym_is(p, name, "arm32")) 403 *out = 5; 404 else if (toy_sym_is(p, name, "rv32")) 405 *out = 6; 406 else if (toy_sym_is(p, name, "wasm")) 407 *out = 7; 408 else { 409 toy_error(p, p->cur.loc, "unknown dot constant"); 410 return 0; 411 } 412 return 1; 413 } 414 415 int toy_parse_switch_label_value(ToyParser* p, KitCgTypeId selector_ty, 416 int64_t* out) { 417 ToyNamedType* named; 418 KitSym value_name; 419 size_t i; 420 if (p->cur.kind != TOK_DOT) return toy_parse_number_arg(p, out); 421 named = toy_find_named_type_by_type(p, selector_ty); 422 if (!named || named->kind != TOY_NAMED_ENUM) 423 return toy_parse_dot_constant_value(p, out); 424 toy_parser_advance(p); /* . */ 425 if (p->cur.kind != TOK_IDENT) { 426 toy_error(p, p->cur.loc, "expected enum value"); 427 return 0; 428 } 429 value_name = toy_tok_sym(p, p->cur); 430 toy_parser_advance(p); 431 for (i = 0; i < named->nenum_values; ++i) { 432 if (named->enum_values[i].name == value_name) { 433 *out = named->enum_values[i].value; 434 return 1; 435 } 436 } 437 toy_error(p, p->cur.loc, "unknown enum value"); 438 return 0; 439 } 440 441 int toy_parse_symbol_feature_const(ToyParser* p, KitCgSymbolFeature* out) { 442 static const ToyConstRow rows[] = { 443 {"weak", KIT_CG_SYMFEAT_WEAK}, 444 {"protected_visibility", KIT_CG_SYMFEAT_PROTECTED_VISIBILITY}, 445 {"dllimport", KIT_CG_SYMFEAT_DLLIMPORT}, 446 {"dllexport", KIT_CG_SYMFEAT_DLLEXPORT}, 447 {"comdat", KIT_CG_SYMFEAT_COMDAT}, 448 {"common", KIT_CG_SYMFEAT_COMMON}, 449 {"merge_sections", KIT_CG_SYMFEAT_MERGE_SECTIONS}, 450 {"constructor_priority", KIT_CG_SYMFEAT_CONSTRUCTOR_PRIORITY}, 451 {"tls_local_exec", KIT_CG_SYMFEAT_TLS_LOCAL_EXEC}, 452 {"tls_initial_exec", KIT_CG_SYMFEAT_TLS_INITIAL_EXEC}, 453 {"tls_local_dynamic", KIT_CG_SYMFEAT_TLS_LOCAL_DYNAMIC}, 454 {"tls_general_dynamic", KIT_CG_SYMFEAT_TLS_GENERAL_DYNAMIC}, 455 }; 456 uint64_t v; 457 if (!toy_parse_dot_const(p, rows, sizeof rows / sizeof rows[0], 1, 458 "symbol feature", "symbol feature", &v)) 459 return 0; 460 *out = (KitCgSymbolFeature)v; 461 return 1; 462 } 463 464 int toy_parse_backend_feature_const(ToyParser* p, uint64_t* out) { 465 static const ToyConstRow rows[] = { 466 {"unaligned_memory", KIT_CG_BACKEND_UNALIGNED_MEMORY}, 467 {"strict_alignment", KIT_CG_BACKEND_STRICT_ALIGNMENT}, 468 {"red_zone", KIT_CG_BACKEND_RED_ZONE}, 469 {"simd", KIT_CG_BACKEND_SIMD}, 470 {"pointer_auth", KIT_CG_BACKEND_POINTER_AUTH}, 471 {"branch_protection", KIT_CG_BACKEND_BRANCH_PROTECTION}, 472 }; 473 return toy_parse_dot_const(p, rows, sizeof rows / sizeof rows[0], 1, 474 "backend feature", "backend feature", out); 475 } 476 477 int toy_parse_intrinsic_const(ToyParser* p, KitCgIntrinsic* out) { 478 static const ToyConstRow rows[] = { 479 {"cpu_nop", KIT_CG_INTRIN_CPU_NOP}, 480 {"cpu_yield", KIT_CG_INTRIN_CPU_YIELD}, 481 {"wfi", KIT_CG_INTRIN_WFI}, 482 {"wfe", KIT_CG_INTRIN_WFE}, 483 {"sev", KIT_CG_INTRIN_SEV}, 484 {"isb", KIT_CG_INTRIN_ISB}, 485 {"dmb", KIT_CG_INTRIN_DMB}, 486 {"dsb", KIT_CG_INTRIN_DSB}, 487 {"irq_save", KIT_CG_INTRIN_IRQ_SAVE}, 488 {"irq_restore", KIT_CG_INTRIN_IRQ_RESTORE}, 489 {"irq_enable", KIT_CG_INTRIN_IRQ_ENABLE}, 490 {"irq_disable", KIT_CG_INTRIN_IRQ_DISABLE}, 491 {"syscall", KIT_CG_INTRIN_SYSCALL}, 492 {"coro_switch", KIT_CG_INTRIN_CORO_SWITCH}, 493 }; 494 uint64_t v; 495 if (!toy_parse_dot_const(p, rows, sizeof rows / sizeof rows[0], 1, 496 "intrinsic name", "intrinsic", &v)) 497 return 0; 498 *out = (KitCgIntrinsic)v; 499 return 1; 500 } 501 502 int toy_parse_rounding_const(ToyParser* p, KitCgRounding* out) { 503 static const ToyConstRow rows[] = { 504 {"default", KIT_CG_ROUND_DEFAULT}, 505 {"nearest_even", KIT_CG_ROUND_NEAREST_EVEN}, 506 {"toward_zero", KIT_CG_ROUND_TOWARD_ZERO}, 507 {"down", KIT_CG_ROUND_DOWN}, 508 {"up", KIT_CG_ROUND_UP}, 509 }; 510 uint64_t v; 511 if (!toy_parse_dot_const(p, rows, sizeof rows / sizeof rows[0], 0, NULL, 512 "rounding mode", &v)) 513 return 0; 514 *out = (KitCgRounding)v; 515 return 1; 516 } 517 518 int toy_validate_bit_range(ToyParser* p, KitCgTypeId ty, int64_t lo, 519 int64_t width, int allow_full_width) { 520 uint32_t type_width; 521 if (!toy_type_is_intlike(p, ty) || lo < 0 || width <= 0) return 0; 522 type_width = toy_type_int_width(p, ty); 523 if (width > (int64_t)type_width) return 0; 524 if (!allow_full_width && width >= 64) return 0; 525 if (lo > (int64_t)type_width || width > (int64_t)type_width - lo) return 0; 526 return 1; 527 } 528 529 int toy_target_code(ToyParser* p) { 530 switch (p->target.arch) { 531 case KIT_ARCH_ARM_64: 532 return 1; 533 case KIT_ARCH_X86_64: 534 return 2; 535 case KIT_ARCH_RV64: 536 return 3; 537 case KIT_ARCH_RV32: 538 return 6; 539 case KIT_ARCH_ARM_32: 540 return 5; /* matches the `.arm32` dot-constant selector */ 541 case KIT_ARCH_WASM: 542 return 7; 543 default: 544 return 0; 545 } 546 } 547 548 int toy_parse_arch_string(ToyParser* p, KitSym* out, size_t* len_out) { 549 if (p->cur.kind == TOK_STRING) return toy_parse_string_sym(p, out, len_out); 550 551 toy_error(p, p->cur.loc, "expected asm template"); 552 return 0; 553 } 554 555 static int toy_emit_var_addr(ToyParser* p, KitSym name) { 556 ToyVar* v = toy_find_var(p, name); 557 if (v) { 558 toy_push_var_addr(p, v); 559 return 1; 560 } 561 { 562 ToyGlobal* g = toy_find_global(p, name); 563 if (g) { 564 kit_cg_push_symbol_addr(p->cg, toy_global_cur_sym(p, g), 0); 565 return 1; 566 } 567 } 568 return 0; 569 } 570 571 KitCgTypeId toy_emit_var_lvalue(ToyParser* p, KitSym name) { 572 ToyVar* v = toy_find_var(p, name); 573 if (v) { 574 toy_push_var_lvalue(p, v); 575 return v->type; 576 } 577 { 578 ToyGlobal* g = toy_find_global(p, name); 579 if (g) { 580 kit_cg_push_symbol_addr(p->cg, toy_global_cur_sym(p, g), 0); 581 return g->type; 582 } 583 } 584 return KIT_CG_TYPE_NONE; 585 } 586 587 static KitCgTypeId toy_type_id_cg_or_none(ToyParser* p, ToyTypeId id) { 588 KitCgTypeId ty = toy_type_resolved_cg(p, id); 589 return ty != KIT_CG_TYPE_NONE ? ty : toy_type_cg(p, id); 590 } 591 592 static void toy_store_tos_to_local(ToyParser* p, KitCgLocal local, 593 KitCgTypeId ty) { 594 kit_cg_push_local(p->cg, local); 595 kit_cg_swap(p->cg); 596 kit_cg_store(p->cg, toy_mem_access(p, ty)); 597 } 598 599 /* Consumes [slice_base, idx] where slice_base is a pointer to the slice 600 * record. Produces [elem_ptr] -- a pointer-rvalue to the element. */ 601 KitCgTypeId toy_emit_slice_index_lvalue(ToyParser* p, KitCgTypeId slice_ty, 602 ToyTypeId slice_toy_type, 603 ToyTypeId* elem_toy_out) { 604 ToyTypeId elem_toy = toy_type_slice_elem(p, slice_toy_type); 605 KitCgTypeId elem_ty = toy_type_id_cg_or_none(p, elem_toy); 606 const KitCgRecordLayout* L = kit_cg_type_record_layout(p->c, slice_ty); 607 KitCgLocal idx_slot; 608 uint64_t ptr_field_off; 609 KitCgTypeId ptr_field_type; 610 if (elem_ty == KIT_CG_TYPE_NONE || 611 kit_cg_type_kind(p->c, slice_ty) != KIT_CG_TYPE_RECORD || !L || 612 L->nfields < 1) { 613 toy_error(p, p->cur.loc, "cannot index non-array/non-pointer"); 614 return KIT_CG_TYPE_NONE; 615 } 616 ptr_field_off = L->fields[0].offset; 617 ptr_field_type = L->fields[0].type; 618 /* Stash the index, then load the slice's ptr field, then re-push idx 619 * and compute element pointer. */ 620 idx_slot = kit_cg_local(p->cg, p->size_type, toy_slot_attrs(0)); 621 toy_store_tos_to_local(p, idx_slot, p->size_type); 622 kit_cg_deref(p->cg, (int64_t)ptr_field_off); 623 kit_cg_load(p->cg, toy_mem_access(p, ptr_field_type)); 624 kit_cg_push_local(p->cg, idx_slot); 625 kit_cg_load(p->cg, toy_mem_access(p, p->size_type)); 626 toy_addr_index(p, kit_cg_type_size(p->c, elem_ty), 627 kit_cg_type_ptr(p->c, elem_ty, 0)); 628 if (elem_toy_out) *elem_toy_out = elem_toy; 629 return elem_ty; 630 } 631 632 KitCgTypeId toy_emit_slice_value(ToyParser* p, KitCgTypeId base_ty, 633 ToyTypeId base_toy_type, KitCgTypeId start_ty, 634 KitCgTypeId end_ty, ToyTypeId* slice_toy_out) { 635 ToyTypeId elem_toy = TOY_TYPE_NONE; 636 KitCgTypeId elem_ty = KIT_CG_TYPE_NONE; 637 ToyTypeId slice_toy; 638 KitCgTypeId slice_ty; 639 KitCgTypeId ptr_field_type = KIT_CG_TYPE_NONE; 640 KitCgLocal start_slot; 641 KitCgLocal end_slot; 642 KitCgLocal result_slot; 643 644 if (start_ty != p->size_type || end_ty != p->size_type) { 645 toy_error(p, p->cur.loc, "slice bounds must be isize"); 646 return KIT_CG_TYPE_NONE; 647 } 648 649 if (kit_cg_type_kind(p->c, base_ty) == KIT_CG_TYPE_ARRAY) { 650 elem_ty = kit_cg_type_array_elem(p->c, base_ty); 651 elem_toy = toy_type_array_elem(p, base_toy_type); 652 } else if (toy_type_is_slice(p, base_toy_type)) { 653 elem_toy = toy_type_slice_elem(p, base_toy_type); 654 elem_ty = toy_type_id_cg_or_none(p, elem_toy); 655 } 656 if (elem_toy == TOY_TYPE_NONE && elem_ty != KIT_CG_TYPE_NONE) 657 elem_toy = toy_type_from_cg(p, elem_ty); 658 if (elem_ty == KIT_CG_TYPE_NONE || elem_toy == TOY_TYPE_NONE) { 659 toy_error(p, p->cur.loc, "cannot slice non-array/non-slice"); 660 return KIT_CG_TYPE_NONE; 661 } 662 663 slice_toy = toy_type_register_slice(p, elem_ty, elem_toy); 664 slice_ty = toy_type_cg(p, slice_toy); 665 { 666 uint64_t ptr_off = 0; 667 uint64_t len_off = 0; 668 const KitCgRecordLayout* L = kit_cg_type_record_layout(p->c, slice_ty); 669 if (slice_ty == KIT_CG_TYPE_NONE || !L || L->nfields < 2) { 670 toy_error(p, p->cur.loc, "failed to create slice type"); 671 return KIT_CG_TYPE_NONE; 672 } 673 ptr_off = L->fields[0].offset; 674 ptr_field_type = L->fields[0].type; 675 len_off = L->fields[1].offset; 676 677 end_slot = kit_cg_local(p->cg, p->size_type, toy_slot_attrs(0)); 678 toy_store_tos_to_local(p, end_slot, p->size_type); 679 start_slot = kit_cg_local(p->cg, p->size_type, toy_slot_attrs(0)); 680 toy_store_tos_to_local(p, start_slot, p->size_type); 681 682 result_slot = kit_cg_local(p->cg, slice_ty, toy_slot_attrs(0)); 683 /* TOS = [base] (slice lvalue/pointer or array lvalue/pointer). */ 684 if (toy_type_is_slice(p, base_toy_type)) { 685 /* Replace slice base with its data pointer (a pointer-rvalue). */ 686 kit_cg_deref(p->cg, (int64_t)ptr_off); 687 kit_cg_load(p->cg, toy_mem_access(p, ptr_field_type)); 688 } else { 689 /* Array base: TOS is a pointer-rvalue (callers always project 690 * to a pointer for array/slice bases now). Bitcast to *elem. */ 691 kit_cg_bitcast(p->cg, kit_cg_type_ptr(p->c, elem_ty, 0)); 692 } 693 /* Compute (base + start * sizeof(elem)) as a pointer to the slice's 694 * first element. */ 695 kit_cg_push_local(p->cg, start_slot); 696 kit_cg_load(p->cg, toy_mem_access(p, p->size_type)); 697 toy_addr_index(p, kit_cg_type_size(p->c, elem_ty), 698 kit_cg_type_ptr(p->c, elem_ty, 0)); 699 /* Store the data pointer into result_slot.ptr. */ 700 kit_cg_push_local(p->cg, result_slot); 701 kit_cg_addr(p->cg); 702 kit_cg_deref(p->cg, (int64_t)ptr_off); 703 kit_cg_swap(p->cg); 704 kit_cg_store(p->cg, toy_mem_access(p, ptr_field_type)); 705 706 /* len = end - start; store into result_slot.len. */ 707 kit_cg_push_local(p->cg, result_slot); 708 kit_cg_addr(p->cg); 709 kit_cg_deref(p->cg, (int64_t)len_off); 710 kit_cg_push_local(p->cg, end_slot); 711 kit_cg_load(p->cg, toy_mem_access(p, p->size_type)); 712 kit_cg_push_local(p->cg, start_slot); 713 kit_cg_load(p->cg, toy_mem_access(p, p->size_type)); 714 kit_cg_int_binop(p->cg, KIT_CG_INT_SUB, 0); 715 kit_cg_store(p->cg, toy_mem_access(p, p->size_type)); 716 } 717 718 /* Hand back the slice record as a pointer VALUE (its address), matching the 719 * "records/slices are pointer VALUEs" shape the downstream record-copy and 720 * slice-index paths consume. */ 721 kit_cg_push_local_addr(p->cg, result_slot); 722 if (slice_toy_out) *slice_toy_out = slice_toy; 723 p->last_type = slice_toy; 724 return slice_ty; 725 } 726 727 int toy_parse_va_list_addr_arg(ToyParser* p) { 728 KitSym name; 729 ToyVar* v; 730 if (p->cur.kind != TOK_IDENT) { 731 toy_error(p, p->cur.loc, "expected va_list identifier"); 732 return 0; 733 } 734 name = toy_tok_sym(p, p->cur); 735 v = toy_find_var(p, name); 736 if (!v || v->type != p->va_list_type) { 737 toy_error(p, p->cur.loc, "expected va_list local"); 738 return 0; 739 } 740 toy_parser_advance(p); 741 return toy_emit_var_addr(p, name); 742 } 743 744 static KitCgTypeId toy_parse_expr_primary(ToyParser* p) { 745 toy_set_loc(p); 746 if (p->cur.kind == TOK_AT) { 747 KitSym name; 748 ToyToken at_tok = p->cur; 749 toy_parser_advance(p); 750 if (p->cur.kind != TOK_IDENT) { 751 toy_error(p, p->cur.loc, "expected builtin name after '@'"); 752 return KIT_CG_TYPE_NONE; 753 } 754 name = toy_tok_sym(p, p->cur); 755 toy_parser_advance(p); 756 757 if (p->cur.kind == TOK_LT) { 758 int recognized = 0; 759 KitCgTypeId builtin_ty = toy_parse_generic_builtin(p, name, &recognized); 760 if (recognized) { 761 if (builtin_ty != KIT_CG_TYPE_NONE) 762 toy_note_builtin_result_type(p, builtin_ty); 763 return builtin_ty; 764 } 765 } 766 767 if (p->cur.kind == TOK_LPAREN) { 768 int recognized = 0; 769 KitCgTypeId builtin_ty = toy_parse_builtin_call(p, name, &recognized); 770 if (recognized) { 771 if (builtin_ty != KIT_CG_TYPE_NONE) 772 toy_note_builtin_result_type(p, builtin_ty); 773 return builtin_ty; 774 } 775 } 776 777 toy_error(p, at_tok.loc, "unknown builtin"); 778 return KIT_CG_TYPE_NONE; 779 } 780 781 if (p->cur.kind == TOK_NUMBER) { 782 if (p->cur.is_float) { 783 kit_cg_push_float(p->cg, p->cur.float_value, 784 toy_builtin_type(p, KIT_CG_BUILTIN_F64)); 785 toy_parser_advance(p); 786 p->last_type = 787 toy_type_from_cg(p, toy_builtin_type(p, KIT_CG_BUILTIN_F64)); 788 return toy_builtin_type(p, KIT_CG_BUILTIN_F64); 789 } 790 { 791 KitCgTypeId lit_ty = toy_int_literal_type(p, p->cur.int_value); 792 kit_cg_push_int(p->cg, (uint64_t)p->cur.int_value, lit_ty); 793 toy_parser_advance(p); 794 p->last_type = toy_type_from_cg(p, lit_ty); 795 return lit_ty; 796 } 797 } 798 799 if (p->cur.kind == TOK_IDENT) { 800 KitSym name = toy_tok_sym(p, p->cur); 801 ToyToken ident_tok = p->cur; 802 toy_parser_advance(p); 803 804 if (toy_sym_is(p, name, "true") || toy_sym_is(p, name, "false")) { 805 kit_cg_push_int(p->cg, toy_sym_is(p, name, "true") ? 1u : 0u, 806 toy_builtin_type(p, KIT_CG_BUILTIN_BOOL)); 807 p->last_type = 808 toy_type_from_cg(p, toy_builtin_type(p, KIT_CG_BUILTIN_BOOL)); 809 return toy_builtin_type(p, KIT_CG_BUILTIN_BOOL); 810 } 811 812 if (toy_sym_is(p, name, "NULL")) { 813 kit_cg_push_int(p->cg, 0, p->int_type); 814 p->last_type = TOY_TYPE_NONE; 815 return p->int_type; 816 } 817 818 if (p->cur.kind == TOK_LT) { 819 int recognized = 0; 820 KitCgTypeId builtin_ty = toy_parse_generic_builtin(p, name, &recognized); 821 if (recognized) return builtin_ty; 822 } 823 824 if (p->cur.kind == TOK_LPAREN) { 825 /* Function call */ 826 int recognized = 0; 827 KitCgTypeId builtin_ty = toy_parse_builtin_call(p, name, &recognized); 828 if (recognized) return builtin_ty; 829 830 ToyFn* fn = toy_find_fn(p, name); 831 toy_parser_advance(p); /* ( */ 832 833 size_t nargs = 0; 834 if (fn) { 835 if (!toy_parse_call_args(p, ident_tok, fn->type, fn->toy_params, 836 fn->nparams, &nargs)) 837 return KIT_CG_TYPE_NONE; 838 { 839 KitCgCallAttrs attrs; 840 memset(&attrs, 0, sizeof attrs); 841 attrs.inline_policy = fn->func_attrs.inline_policy; 842 kit_cg_call_symbol(p->cg, toy_fn_cur_sym(p, fn), (uint32_t)nargs, 843 attrs); 844 } 845 /* An aggregate return is a PLACE; project it to a pointer VALUE so it 846 * matches the records-are-pointers invariant used downstream. */ 847 if (kit_cg_type_kind(p->c, fn->ret) == KIT_CG_TYPE_RECORD) 848 kit_cg_addr(p->cg); 849 p->last_type = fn->toy_ret; 850 return fn->ret; 851 } 852 853 KitCgTypeId callee_ty = toy_push_named_rvalue(p, name); 854 ToyTypeId callee_toy_type = p->last_type; 855 const ToyType* source_fn_type = NULL; 856 if (callee_ty == KIT_CG_TYPE_NONE) { 857 toy_error(p, ident_tok.loc, "undefined function '%.*s'", 858 (int)ident_tok.text_len, (const char*)ident_tok.text); 859 return KIT_CG_TYPE_NONE; 860 } 861 KitCgTypeId fn_ty = toy_ptr_pointee_func_type(p, callee_ty); 862 if (fn_ty == KIT_CG_TYPE_NONE) { 863 toy_error(p, ident_tok.loc, "callee is not a function pointer"); 864 return KIT_CG_TYPE_NONE; 865 } 866 source_fn_type = toy_type_get(p, toy_type_pointee(p, callee_toy_type)); 867 if (source_fn_type && source_fn_type->kind != TOY_TYPE_FUNC) 868 source_fn_type = NULL; 869 if (!toy_parse_call_args(p, ident_tok, fn_ty, 870 source_fn_type ? source_fn_type->params : NULL, 871 source_fn_type ? source_fn_type->nparams : 0, 872 &nargs)) 873 return KIT_CG_TYPE_NONE; 874 kit_cg_call_default(p->cg, (uint32_t)nargs, fn_ty); 875 if (kit_cg_type_kind(p->c, toy_cg_func_ret(p, fn_ty)) == 876 KIT_CG_TYPE_RECORD) 877 kit_cg_addr(p->cg); 878 p->last_type = source_fn_type 879 ? source_fn_type->ret 880 : toy_type_from_cg(p, toy_cg_func_ret(p, fn_ty)); 881 return toy_cg_func_ret(p, fn_ty); 882 } 883 884 if (p->cur.kind == TOK_LBRACKET || p->cur.kind == TOK_DOT) { 885 ToyVar* v = toy_find_var(p, name); 886 if (v && (kit_cg_type_kind(p->c, v->type) == KIT_CG_TYPE_ARRAY || 887 kit_cg_type_kind(p->c, v->type) == KIT_CG_TYPE_RECORD)) { 888 if (kit_cg_type_kind(p->c, v->type) == KIT_CG_TYPE_ARRAY) { 889 /* Array slicing/indexing wants a pointer root for address math. */ 890 toy_push_var_addr(p, v); 891 } else { 892 toy_push_var_lvalue(p, v); 893 } 894 p->last_type = v->toy_type; 895 return v->type; 896 } 897 { 898 ToyGlobal* g = toy_find_global(p, name); 899 if (g && (kit_cg_type_kind(p->c, g->type) == KIT_CG_TYPE_ARRAY || 900 kit_cg_type_kind(p->c, g->type) == KIT_CG_TYPE_RECORD)) { 901 kit_cg_push_symbol_addr(p->cg, toy_global_cur_sym(p, g), 0); 902 p->last_type = g->toy_type; 903 return g->type; 904 } 905 } 906 } 907 908 { 909 ToyVar* v = toy_find_var(p, name); 910 if (v && toy_type_is_slice(p, v->toy_type)) { 911 toy_push_var_lvalue(p, v); 912 p->last_type = v->toy_type; 913 return v->type; 914 } 915 { 916 ToyGlobal* g = toy_find_global(p, name); 917 if (g && toy_type_is_slice(p, g->toy_type)) { 918 kit_cg_push_symbol_addr(p->cg, toy_global_cur_sym(p, g), 0); 919 p->last_type = g->toy_type; 920 return g->type; 921 } 922 } 923 } 924 925 { 926 KitCgTypeId ty = toy_push_named_rvalue(p, name); 927 if (ty != KIT_CG_TYPE_NONE) return ty; 928 } 929 toy_error(p, ident_tok.loc, "undefined variable '%.*s'", 930 (int)ident_tok.text_len, (const char*)ident_tok.text); 931 return KIT_CG_TYPE_NONE; 932 } 933 934 if (p->cur.kind == TOK_LPAREN) { 935 toy_parser_advance(p); 936 KitCgTypeId ty = toy_parse_expr(p); 937 if (ty == KIT_CG_TYPE_NONE) return KIT_CG_TYPE_NONE; 938 if (!toy_parser_expect(p, TOK_RPAREN)) { 939 toy_error(p, p->cur.loc, "expected ')'"); 940 return KIT_CG_TYPE_NONE; 941 } 942 return ty; 943 } 944 945 toy_error(p, p->cur.loc, "expected expression"); 946 return KIT_CG_TYPE_NONE; 947 } 948 949 static KitCgTypeId toy_parse_expr_postfix(ToyParser* p) { 950 KitCgTypeId ty = toy_parse_expr_primary(p); 951 ToyTypeId toy_ty = p->last_type; 952 if (p->tail_call_expr) return ty; 953 while (ty != KIT_CG_TYPE_NONE) { 954 if (toy_parser_match(p, TOK_DOTSTAR)) { 955 if (kit_cg_type_kind(p->c, ty) != KIT_CG_TYPE_PTR) { 956 toy_error(p, p->cur.loc, "cannot dereference non-pointer"); 957 return KIT_CG_TYPE_NONE; 958 } 959 ty = kit_cg_type_ptr_pointee(p->c, ty); 960 toy_ty = toy_type_pointee(p, toy_ty); 961 /* TOS is a pointer VALUE; deref it to a PLACE, then load. */ 962 kit_cg_deref(p->cg, 0); 963 kit_cg_load(p->cg, toy_mem_access(p, ty)); 964 p->last_type = toy_ty != TOY_TYPE_NONE ? toy_ty : toy_type_from_cg(p, ty); 965 continue; 966 } 967 968 if (toy_parser_match(p, TOK_LBRACKET)) { 969 KitCgTypeId idx_ty = toy_parse_expr(p); 970 if (idx_ty == KIT_CG_TYPE_NONE) return KIT_CG_TYPE_NONE; 971 if (!toy_type_can_implicitly_cast(p, idx_ty, p->size_type)) { 972 toy_error(p, p->cur.loc, "index must be isize"); 973 return KIT_CG_TYPE_NONE; 974 } 975 if (!toy_emit_implicit_cast(p, idx_ty, p->size_type)) 976 return KIT_CG_TYPE_NONE; 977 idx_ty = p->size_type; 978 if (toy_parser_match(p, TOK_COLON)) { 979 KitCgTypeId end_ty = toy_parse_expr(p); 980 ToyTypeId slice_toy_type = TOY_TYPE_NONE; 981 if (end_ty == KIT_CG_TYPE_NONE) return KIT_CG_TYPE_NONE; 982 if (!toy_type_can_implicitly_cast(p, end_ty, p->size_type)) { 983 toy_error(p, p->cur.loc, "slice bounds must be isize"); 984 return KIT_CG_TYPE_NONE; 985 } 986 if (!toy_emit_implicit_cast(p, end_ty, p->size_type)) 987 return KIT_CG_TYPE_NONE; 988 end_ty = p->size_type; 989 if (!toy_parser_expect(p, TOK_RBRACKET)) { 990 toy_error(p, p->cur.loc, "expected ']' after slice"); 991 return KIT_CG_TYPE_NONE; 992 } 993 ty = toy_emit_slice_value(p, ty, toy_ty, idx_ty, end_ty, 994 &slice_toy_type); 995 if (ty == KIT_CG_TYPE_NONE) return KIT_CG_TYPE_NONE; 996 toy_ty = slice_toy_type; 997 p->last_type = toy_ty; 998 continue; 999 } 1000 if (!toy_parser_expect(p, TOK_RBRACKET)) { 1001 toy_error(p, p->cur.loc, "expected ']' after index"); 1002 return KIT_CG_TYPE_NONE; 1003 } 1004 if (kit_cg_type_kind(p->c, ty) == KIT_CG_TYPE_PTR) { 1005 KitCgTypeId pointee = kit_cg_type_ptr_pointee(p->c, ty); 1006 ToyTypeId source_pointee = toy_type_pointee(p, toy_ty); 1007 if (kit_cg_type_kind(p->c, pointee) == KIT_CG_TYPE_ARRAY) { 1008 /* TOS = [ptr-to-array, idx]. Cast pointer to *elem so the load 1009 * can apply the array's elem-scale on the next memop. */ 1010 KitCgTypeId elem_ty = kit_cg_type_array_elem(p->c, pointee); 1011 kit_cg_swap(p->cg); 1012 kit_cg_bitcast(p->cg, kit_cg_type_ptr(p->c, elem_ty, 0)); 1013 kit_cg_swap(p->cg); 1014 ty = elem_ty; 1015 toy_ty = toy_type_array_elem(p, source_pointee); 1016 } else { 1017 ty = pointee; 1018 toy_ty = source_pointee; 1019 } 1020 } else if (kit_cg_type_kind(p->c, ty) == KIT_CG_TYPE_ARRAY) { 1021 /* TOS = [ptr-to-array, idx]. Decay the base to *elem so kit_cg_elem 1022 * scales by the element size, not the whole array. */ 1023 KitCgTypeId elem_ty = kit_cg_type_array_elem(p->c, ty); 1024 kit_cg_swap(p->cg); 1025 kit_cg_bitcast(p->cg, kit_cg_type_ptr(p->c, elem_ty, 0)); 1026 kit_cg_swap(p->cg); 1027 ty = elem_ty; 1028 toy_ty = toy_type_array_elem(p, toy_ty); 1029 } else if (toy_type_is_slice(p, toy_ty)) { 1030 ty = toy_emit_slice_index_lvalue(p, ty, toy_ty, &toy_ty); 1031 if (ty == KIT_CG_TYPE_NONE) return KIT_CG_TYPE_NONE; 1032 /* toy_emit_slice_index_lvalue returns an element pointer VALUE. */ 1033 kit_cg_deref(p->cg, 0); 1034 kit_cg_load(p->cg, toy_mem_access(p, ty)); 1035 p->last_type = 1036 toy_ty != TOY_TYPE_NONE ? toy_ty : toy_type_from_cg(p, ty); 1037 continue; 1038 } else { 1039 toy_error(p, p->cur.loc, "cannot index non-array/non-pointer"); 1040 return KIT_CG_TYPE_NONE; 1041 } 1042 /* TOS = [base, idx]; elem yields the element PLACE, then load. */ 1043 kit_cg_elem(p->cg, 0); 1044 kit_cg_load(p->cg, toy_mem_access(p, ty)); 1045 p->last_type = toy_ty != TOY_TYPE_NONE ? toy_ty : toy_type_from_cg(p, ty); 1046 continue; 1047 } 1048 1049 if (toy_parser_match(p, TOK_DOT)) { 1050 KitSym field_name; 1051 uint32_t i, nfields; 1052 int found = 0; 1053 KitCgFieldLayout found_field; 1054 uint64_t found_off = 0; 1055 ToyNamedType* named; 1056 ToyTypeId field_toy_type = TOY_TYPE_NONE; 1057 if (kit_cg_type_kind(p->c, ty) == KIT_CG_TYPE_PTR && 1058 kit_cg_type_kind(p->c, kit_cg_type_ptr_pointee(p->c, ty)) == 1059 KIT_CG_TYPE_RECORD) { 1060 /* TOS is a pointer to the record; the memop accepts it directly, 1061 * so no intermediate op is needed -- we just update `ty`. */ 1062 ty = kit_cg_type_ptr_pointee(p->c, ty); 1063 toy_ty = toy_type_pointee(p, toy_ty); 1064 } 1065 named = toy_find_named_type_by_type(p, ty); 1066 if (p->cur.kind == TOK_NUMBER && !p->cur.is_float) { 1067 uint32_t field_index; 1068 const KitCgRecordLayout* L = kit_cg_type_record_layout(p->c, ty); 1069 if (kit_cg_type_kind(p->c, ty) != KIT_CG_TYPE_RECORD || !L || 1070 p->cur.int_value < 0 || p->cur.int_value >= (int64_t)L->nfields) { 1071 toy_error(p, p->cur.loc, "invalid tuple field"); 1072 return KIT_CG_TYPE_NONE; 1073 } 1074 field_index = (uint32_t)p->cur.int_value; 1075 toy_parser_advance(p); 1076 found_field = L->fields[field_index]; 1077 found_off = found_field.offset; 1078 if (named && field_index < named->nfields) 1079 field_toy_type = named->fields[field_index].toy_type; 1080 ty = found_field.type; 1081 kit_cg_deref(p->cg, (int64_t)found_off); 1082 kit_cg_load(p->cg, toy_mem_access(p, ty)); 1083 if (field_toy_type != TOY_TYPE_NONE) { 1084 KitCgTypeId resolved = toy_type_resolved_cg(p, field_toy_type); 1085 p->last_type = field_toy_type; 1086 toy_ty = field_toy_type; 1087 if (resolved != KIT_CG_TYPE_NONE && resolved != ty) { 1088 if (!toy_emit_checked_cast(p, ty, resolved)) 1089 return KIT_CG_TYPE_NONE; 1090 ty = resolved; 1091 } 1092 } else { 1093 p->last_type = toy_type_from_cg(p, ty); 1094 toy_ty = p->last_type; 1095 } 1096 continue; 1097 } 1098 if (p->cur.kind != TOK_IDENT) { 1099 toy_error(p, p->cur.loc, "expected field name"); 1100 return KIT_CG_TYPE_NONE; 1101 } 1102 field_name = toy_tok_sym(p, p->cur); 1103 toy_parser_advance(p); 1104 if (kit_cg_type_kind(p->c, ty) != KIT_CG_TYPE_RECORD) { 1105 toy_error(p, p->cur.loc, "field access on non-record"); 1106 return KIT_CG_TYPE_NONE; 1107 } 1108 { 1109 const KitCgRecordLayout* L = kit_cg_type_record_layout(p->c, ty); 1110 nfields = L ? L->nfields : 0; 1111 memset(&found_field, 0, sizeof found_field); 1112 for (i = 0; L && i < nfields; ++i) { 1113 if (L->fields[i].name == field_name) { 1114 found = 1; 1115 found_field = L->fields[i]; 1116 found_off = found_field.offset; 1117 if (named && i < named->nfields) 1118 field_toy_type = named->fields[i].toy_type; 1119 break; 1120 } 1121 } 1122 } 1123 if (!found) { 1124 toy_error(p, p->cur.loc, "unknown record field"); 1125 return KIT_CG_TYPE_NONE; 1126 } 1127 ty = found_field.type; 1128 kit_cg_deref(p->cg, (int64_t)found_off); 1129 kit_cg_load(p->cg, toy_mem_access(p, ty)); 1130 if (field_toy_type != TOY_TYPE_NONE) { 1131 KitCgTypeId resolved = toy_type_resolved_cg(p, field_toy_type); 1132 p->last_type = field_toy_type; 1133 toy_ty = field_toy_type; 1134 if (resolved != KIT_CG_TYPE_NONE && resolved != ty) { 1135 if (!toy_emit_checked_cast(p, ty, resolved)) return KIT_CG_TYPE_NONE; 1136 ty = resolved; 1137 } 1138 } else { 1139 p->last_type = toy_type_from_cg(p, ty); 1140 toy_ty = p->last_type; 1141 } 1142 continue; 1143 } 1144 1145 break; 1146 } 1147 return ty; 1148 } 1149 1150 static KitCgTypeId toy_parse_expr_unary(ToyParser* p) { 1151 toy_set_loc(p); 1152 if (toy_parser_match(p, TOK_MINUS)) { 1153 KitCgTypeId ty = toy_parse_expr_unary(p); 1154 if (ty == KIT_CG_TYPE_NONE) return KIT_CG_TYPE_NONE; 1155 if (p->tail_call_expr) { 1156 toy_error(p, p->cur.loc, "tail @call must be returned directly"); 1157 return KIT_CG_TYPE_NONE; 1158 } 1159 if (toy_type_is_float(p, ty)) { 1160 kit_cg_fp_unop(p->cg, KIT_CG_FP_NEG, 0); 1161 return ty; 1162 } 1163 if (!toy_type_is_intlike(p, ty)) { 1164 toy_error(p, p->cur.loc, "invalid operand for unary '-'"); 1165 return KIT_CG_TYPE_NONE; 1166 } 1167 kit_cg_int_unop(p->cg, KIT_CG_INT_NEG, 0); 1168 return ty; 1169 } 1170 1171 if (toy_parser_match(p, TOK_BANG)) { 1172 KitCgTypeId ty = toy_parse_expr_unary(p); 1173 if (ty == KIT_CG_TYPE_NONE) return KIT_CG_TYPE_NONE; 1174 if (p->tail_call_expr) { 1175 toy_error(p, p->cur.loc, "tail @call must be returned directly"); 1176 return KIT_CG_TYPE_NONE; 1177 } 1178 if (!toy_type_is_intlike(p, ty)) { 1179 toy_error(p, p->cur.loc, "invalid operand for '!'"); 1180 return KIT_CG_TYPE_NONE; 1181 } 1182 kit_cg_int_unop(p->cg, KIT_CG_INT_NOT, 0); 1183 return ty; 1184 } 1185 1186 if (toy_parser_match(p, TOK_TILDE)) { 1187 KitCgTypeId ty = toy_parse_expr_unary(p); 1188 if (ty == KIT_CG_TYPE_NONE) return KIT_CG_TYPE_NONE; 1189 if (p->tail_call_expr) { 1190 toy_error(p, p->cur.loc, "tail @call must be returned directly"); 1191 return KIT_CG_TYPE_NONE; 1192 } 1193 if (!toy_type_is_intlike(p, ty)) { 1194 toy_error(p, p->cur.loc, "invalid operand for '~'"); 1195 return KIT_CG_TYPE_NONE; 1196 } 1197 kit_cg_int_unop(p->cg, KIT_CG_INT_BNOT, 0); 1198 return ty; 1199 } 1200 1201 if (toy_parser_match(p, TOK_AMPERSAND)) { 1202 KitSym name; 1203 KitCgTypeId ty; 1204 if (p->cur.kind != TOK_IDENT) { 1205 toy_error(p, p->cur.loc, "expected identifier after '&'"); 1206 return KIT_CG_TYPE_NONE; 1207 } 1208 name = toy_tok_sym(p, p->cur); 1209 toy_parser_advance(p); 1210 1211 if (p->cur.kind == TOK_LBRACKET || p->cur.kind == TOK_DOTSTAR || 1212 p->cur.kind == TOK_DOT) { 1213 /* `&expr` chain. Maintain the invariant that TOS holds a 1214 * pointer-rvalue of type *ty. The chain returns a pointer-rvalue 1215 * directly (no trailing kit_cg_addr needed). */ 1216 ToyTypeId ty_toy = TOY_TYPE_NONE; 1217 { 1218 ToyVar* v = toy_find_var(p, name); 1219 ToyGlobal* g = toy_find_global(p, name); 1220 if (v) { 1221 toy_push_var_addr(p, v); 1222 ty = v->type; 1223 ty_toy = v->toy_type; 1224 } else if (g) { 1225 kit_cg_push_symbol_addr(p->cg, toy_global_cur_sym(p, g), 0); 1226 ty = g->type; 1227 ty_toy = g->toy_type; 1228 } else { 1229 ty = KIT_CG_TYPE_NONE; 1230 } 1231 } 1232 if (ty == KIT_CG_TYPE_NONE) { 1233 toy_error(p, p->cur.loc, "undefined variable"); 1234 return KIT_CG_TYPE_NONE; 1235 } 1236 for (;;) { 1237 if (toy_parser_match(p, TOK_LBRACKET)) { 1238 KitCgTypeId idx_ty = toy_parse_expr(p); 1239 if (idx_ty == KIT_CG_TYPE_NONE) return KIT_CG_TYPE_NONE; 1240 if (!toy_type_can_implicitly_cast(p, idx_ty, p->size_type)) { 1241 toy_error(p, p->cur.loc, "index must be isize"); 1242 return KIT_CG_TYPE_NONE; 1243 } 1244 if (!toy_emit_implicit_cast(p, idx_ty, p->size_type)) 1245 return KIT_CG_TYPE_NONE; 1246 idx_ty = p->size_type; 1247 if (!toy_parser_expect(p, TOK_RBRACKET)) { 1248 toy_error(p, p->cur.loc, "expected ']' after index"); 1249 return KIT_CG_TYPE_NONE; 1250 } 1251 if (kit_cg_type_kind(p->c, ty) == KIT_CG_TYPE_PTR) { 1252 KitCgTypeId pointee = kit_cg_type_ptr_pointee(p->c, ty); 1253 /* TOS holds **T_chain; load the inner pointer first. */ 1254 { 1255 KitCgLocal idx_slot = 1256 kit_cg_local(p->cg, p->size_type, toy_slot_attrs(0)); 1257 kit_cg_push_local(p->cg, idx_slot); 1258 kit_cg_swap(p->cg); 1259 kit_cg_store(p->cg, toy_mem_access(p, p->size_type)); 1260 /* TOS is the chain pointer VALUE (**T); deref to a PLACE and 1261 * load the inner pointer it addresses. */ 1262 kit_cg_deref(p->cg, 0); 1263 kit_cg_load(p->cg, toy_mem_access(p, ty)); 1264 kit_cg_push_local(p->cg, idx_slot); 1265 kit_cg_load(p->cg, toy_mem_access(p, p->size_type)); 1266 } 1267 if (kit_cg_type_kind(p->c, pointee) == KIT_CG_TYPE_ARRAY) { 1268 KitCgTypeId elem_ty = kit_cg_type_array_elem(p->c, pointee); 1269 ty = elem_ty; 1270 ty_toy = toy_type_array_elem(p, toy_type_pointee(p, ty_toy)); 1271 toy_addr_index(p, kit_cg_type_size(p->c, elem_ty), 1272 kit_cg_type_ptr(p->c, elem_ty, 0)); 1273 } else { 1274 ty = pointee; 1275 ty_toy = toy_type_pointee(p, ty_toy); 1276 toy_addr_index(p, kit_cg_type_size(p->c, ty), 1277 kit_cg_type_ptr(p->c, ty, 0)); 1278 } 1279 } else if (kit_cg_type_kind(p->c, ty) == KIT_CG_TYPE_ARRAY) { 1280 KitCgTypeId elem_ty = kit_cg_type_array_elem(p->c, ty); 1281 ty = elem_ty; 1282 ty_toy = toy_type_array_elem(p, ty_toy); 1283 toy_addr_index(p, kit_cg_type_size(p->c, elem_ty), 1284 kit_cg_type_ptr(p->c, elem_ty, 0)); 1285 } else if (toy_type_is_slice(p, ty_toy)) { 1286 ToyTypeId elem_toy = TOY_TYPE_NONE; 1287 ty = toy_emit_slice_index_lvalue(p, ty, ty_toy, &elem_toy); 1288 if (ty == KIT_CG_TYPE_NONE) return KIT_CG_TYPE_NONE; 1289 ty_toy = elem_toy; 1290 } else { 1291 toy_error(p, p->cur.loc, "cannot index non-array/non-pointer"); 1292 return KIT_CG_TYPE_NONE; 1293 } 1294 continue; 1295 } 1296 if (toy_parser_match(p, TOK_DOTSTAR)) { 1297 if (kit_cg_type_kind(p->c, ty) != KIT_CG_TYPE_PTR) { 1298 toy_error(p, p->cur.loc, "cannot dereference non-pointer"); 1299 return KIT_CG_TYPE_NONE; 1300 } 1301 /* TOS = **T (pointer VALUE); deref to PLACE and load to TOS = *T. */ 1302 kit_cg_deref(p->cg, 0); 1303 kit_cg_load(p->cg, toy_mem_access(p, ty)); 1304 ty = kit_cg_type_ptr_pointee(p->c, ty); 1305 ty_toy = toy_type_pointee(p, ty_toy); 1306 continue; 1307 } 1308 if (toy_parser_match(p, TOK_DOT)) { 1309 KitCgFieldLayout field; 1310 uint32_t field_index = 0; 1311 uint64_t foff = 0; 1312 ToyNamedType* named; 1313 if (kit_cg_type_kind(p->c, ty) == KIT_CG_TYPE_PTR && 1314 kit_cg_type_kind(p->c, kit_cg_type_ptr_pointee(p->c, ty)) == 1315 KIT_CG_TYPE_RECORD) { 1316 /* TOS = **Rec (pointer VALUE); deref to PLACE and load to *Rec. */ 1317 kit_cg_deref(p->cg, 0); 1318 kit_cg_load(p->cg, toy_mem_access(p, ty)); 1319 ty = kit_cg_type_ptr_pointee(p->c, ty); 1320 ty_toy = toy_type_pointee(p, ty_toy); 1321 } 1322 if (kit_cg_type_kind(p->c, ty) != KIT_CG_TYPE_RECORD) { 1323 toy_error(p, p->cur.loc, "field access on non-record"); 1324 return KIT_CG_TYPE_NONE; 1325 } 1326 named = toy_find_named_type_by_type(p, ty); 1327 if (p->cur.kind == TOK_NUMBER && !p->cur.is_float) { 1328 const KitCgRecordLayout* L = kit_cg_type_record_layout(p->c, ty); 1329 if (!L || p->cur.int_value < 0 || 1330 p->cur.int_value >= (int64_t)L->nfields) { 1331 toy_error(p, p->cur.loc, "invalid tuple field"); 1332 return KIT_CG_TYPE_NONE; 1333 } 1334 field_index = (uint32_t)p->cur.int_value; 1335 toy_parser_advance(p); 1336 field = L->fields[field_index]; 1337 foff = field.offset; 1338 } else { 1339 KitSym field_name; 1340 if (p->cur.kind != TOK_IDENT) { 1341 toy_error(p, p->cur.loc, "expected field name"); 1342 return KIT_CG_TYPE_NONE; 1343 } 1344 field_name = toy_tok_sym(p, p->cur); 1345 toy_parser_advance(p); 1346 if (!toy_record_field_index(p, ty, field_name, &field_index, 1347 &field)) { 1348 toy_error(p, p->cur.loc, "unknown record field"); 1349 return KIT_CG_TYPE_NONE; 1350 } 1351 foff = field.offset; 1352 } 1353 ty = field.type; 1354 ty_toy = (named && field_index < named->nfields) 1355 ? named->fields[field_index].toy_type 1356 : toy_type_from_cg(p, ty); 1357 toy_addr_offset(p, (int64_t)foff, kit_cg_type_ptr(p->c, ty, 0)); 1358 continue; 1359 } 1360 break; 1361 } 1362 /* TOS already holds a pointer-rvalue of type *ty. */ 1363 { 1364 KitCgTypeId ptr_ty = kit_cg_type_ptr(p->c, ty, 0); 1365 p->last_type = toy_type_register_ptr( 1366 p, ptr_ty, 1367 ty_toy != TOY_TYPE_NONE ? ty_toy : toy_type_from_cg(p, ty), 0); 1368 return ptr_ty; 1369 } 1370 } 1371 1372 { 1373 ToyVar* v = toy_find_var(p, name); 1374 if (v) { 1375 KitCgTypeId ptr_ty = kit_cg_type_ptr(p->c, v->type, 0); 1376 toy_push_var_addr(p, v); 1377 p->last_type = toy_type_register_ptr(p, ptr_ty, v->toy_type, 0); 1378 return ptr_ty; 1379 } else { 1380 ToyGlobal* g = toy_find_global(p, name); 1381 if (g) { 1382 KitCgTypeId ptr_ty = kit_cg_type_ptr(p->c, g->type, 0); 1383 kit_cg_push_symbol_addr(p->cg, toy_global_cur_sym(p, g), 0); 1384 p->last_type = toy_type_register_ptr(p, ptr_ty, g->toy_type, 0); 1385 return ptr_ty; 1386 } else { 1387 ToyFn* fn = toy_find_fn(p, name); 1388 if (fn) { 1389 KitCgTypeId ptr_ty = kit_cg_type_ptr(p->c, fn->type, 0); 1390 kit_cg_push_symbol_addr(p->cg, toy_fn_cur_sym(p, fn), 0); 1391 p->last_type = toy_type_register_ptr(p, ptr_ty, fn->toy_type, 0); 1392 return ptr_ty; 1393 } 1394 } 1395 toy_error(p, p->cur.loc, "undefined variable"); 1396 return KIT_CG_TYPE_NONE; 1397 } 1398 } 1399 } 1400 1401 return toy_parse_expr_postfix(p); 1402 } 1403 1404 static KitCgTypeId toy_parse_expr_cast(ToyParser* p) { 1405 KitCgTypeId ty = toy_parse_expr_unary(p); 1406 while (ty != KIT_CG_TYPE_NONE && !p->tail_call_expr && 1407 toy_parser_match(p, TOK_AS)) { 1408 KitCgTypeId dst = toy_parse_type(p); 1409 if (dst == KIT_CG_TYPE_NONE) return KIT_CG_TYPE_NONE; 1410 if (!toy_emit_cast(p, ty, dst)) return KIT_CG_TYPE_NONE; 1411 ty = dst; 1412 } 1413 return ty; 1414 } 1415 1416 static KitCgTypeId toy_parse_expr_mul(ToyParser* p) { 1417 KitCgTypeId ty = toy_parse_expr_cast(p); 1418 if (ty == KIT_CG_TYPE_NONE) return KIT_CG_TYPE_NONE; 1419 while (p->cur.kind == TOK_STAR || p->cur.kind == TOK_SLASH || 1420 p->cur.kind == TOK_PERCENT) { 1421 if (p->tail_call_expr) break; 1422 ToyTokenKind op = p->cur.kind; 1423 KitCgIntBinOp binop; 1424 if (!toy_note_expr_island(p, TOY_EXPR_ISLAND_ARITH)) 1425 return KIT_CG_TYPE_NONE; 1426 toy_parser_advance(p); 1427 KitCgTypeId ty2 = toy_parse_expr_cast(p); 1428 if (ty2 == KIT_CG_TYPE_NONE) return KIT_CG_TYPE_NONE; 1429 if (toy_reject_tail_call_operand(p)) return KIT_CG_TYPE_NONE; 1430 if (toy_type_is_intlike(p, ty) && toy_type_is_intlike(p, ty2)) { 1431 if (!toy_promote_binary_int_operands(p, &ty, &ty2)) { 1432 toy_error(p, p->cur.loc, 1433 "arithmetic operands must have same numeric type"); 1434 return KIT_CG_TYPE_NONE; 1435 } 1436 } else if (ty != ty2 || !toy_type_is_float(p, ty)) { 1437 toy_error(p, p->cur.loc, 1438 "arithmetic operands must have same numeric type"); 1439 return KIT_CG_TYPE_NONE; 1440 } 1441 if (toy_type_is_float(p, ty)) { 1442 KitCgFpBinOp fp_op; 1443 if (op == TOK_PERCENT) { 1444 toy_error(p, p->cur.loc, "floating-point remainder is unsupported"); 1445 return KIT_CG_TYPE_NONE; 1446 } 1447 switch (op) { 1448 case TOK_STAR: 1449 fp_op = KIT_CG_FP_MUL; 1450 break; 1451 case TOK_SLASH: 1452 fp_op = KIT_CG_FP_DIV; 1453 break; 1454 default: 1455 return KIT_CG_TYPE_NONE; 1456 } 1457 kit_cg_fp_binop(p->cg, fp_op, 0); 1458 } else { 1459 switch (op) { 1460 case TOK_STAR: 1461 binop = KIT_CG_INT_MUL; 1462 break; 1463 case TOK_SLASH: 1464 binop = KIT_CG_INT_SDIV; 1465 break; 1466 case TOK_PERCENT: 1467 binop = KIT_CG_INT_SREM; 1468 break; 1469 default: 1470 return KIT_CG_TYPE_NONE; 1471 } 1472 kit_cg_int_binop(p->cg, binop, 0); 1473 } 1474 toy_note_cg_result_type(p, ty); 1475 } 1476 return ty; 1477 } 1478 1479 static KitCgTypeId toy_parse_expr_add(ToyParser* p) { 1480 KitCgTypeId ty = toy_parse_expr_mul(p); 1481 if (ty == KIT_CG_TYPE_NONE) return KIT_CG_TYPE_NONE; 1482 while (p->cur.kind == TOK_PLUS || p->cur.kind == TOK_MINUS) { 1483 if (p->tail_call_expr) break; 1484 ToyTokenKind op = p->cur.kind; 1485 KitCgIntBinOp binop = (op == TOK_PLUS) ? KIT_CG_INT_ADD : KIT_CG_INT_SUB; 1486 if (!toy_note_expr_island(p, TOY_EXPR_ISLAND_ARITH)) 1487 return KIT_CG_TYPE_NONE; 1488 toy_parser_advance(p); 1489 KitCgTypeId ty2 = toy_parse_expr_mul(p); 1490 if (ty2 == KIT_CG_TYPE_NONE) return KIT_CG_TYPE_NONE; 1491 if (toy_reject_tail_call_operand(p)) return KIT_CG_TYPE_NONE; 1492 if (toy_type_is_intlike(p, ty) && toy_type_is_intlike(p, ty2)) { 1493 if (!toy_promote_binary_int_operands(p, &ty, &ty2)) { 1494 toy_error(p, p->cur.loc, 1495 "arithmetic operands must have same numeric type"); 1496 return KIT_CG_TYPE_NONE; 1497 } 1498 } else if (ty != ty2 || !toy_type_is_float(p, ty)) { 1499 toy_error(p, p->cur.loc, 1500 "arithmetic operands must have same numeric type"); 1501 return KIT_CG_TYPE_NONE; 1502 } 1503 if (toy_type_is_float(p, ty)) { 1504 kit_cg_fp_binop(p->cg, op == TOK_PLUS ? KIT_CG_FP_ADD : KIT_CG_FP_SUB, 0); 1505 } else { 1506 kit_cg_int_binop(p->cg, binop, 0); 1507 } 1508 toy_note_cg_result_type(p, ty); 1509 } 1510 return ty; 1511 } 1512 1513 static KitCgTypeId toy_parse_expr_cmp(ToyParser* p) { 1514 KitCgTypeId ty = toy_parse_expr_add(p); 1515 if (ty == KIT_CG_TYPE_NONE) return KIT_CG_TYPE_NONE; 1516 if (!p->tail_call_expr && (p->cur.kind == TOK_EQEQ || p->cur.kind == TOK_NE || 1517 p->cur.kind == TOK_LT || p->cur.kind == TOK_GT || 1518 p->cur.kind == TOK_LE || p->cur.kind == TOK_GE)) { 1519 ToyTokenKind op = p->cur.kind; 1520 KitCgIntCmpOp cmp; 1521 if (!toy_note_expr_island(p, TOY_EXPR_ISLAND_CMP)) return KIT_CG_TYPE_NONE; 1522 toy_parser_advance(p); 1523 KitCgTypeId ty2 = toy_parse_expr_add(p); 1524 if (ty2 == KIT_CG_TYPE_NONE) return KIT_CG_TYPE_NONE; 1525 if (toy_reject_tail_call_operand(p)) return KIT_CG_TYPE_NONE; 1526 if (toy_type_is_intlike(p, ty) && toy_type_is_intlike(p, ty2)) { 1527 if (!toy_promote_binary_int_operands(p, &ty, &ty2)) { 1528 toy_error(p, p->cur.loc, "comparison operands must have same type"); 1529 return KIT_CG_TYPE_NONE; 1530 } 1531 } else if (ty != ty2) { 1532 toy_error(p, p->cur.loc, "comparison operands must have same type"); 1533 return KIT_CG_TYPE_NONE; 1534 } 1535 if (toy_type_is_float(p, ty)) { 1536 KitCgFpCmpOp fp_cmp; 1537 switch (op) { 1538 case TOK_EQEQ: 1539 fp_cmp = KIT_CG_FP_OEQ; 1540 break; 1541 case TOK_NE: 1542 /* `!=` on floats is unordered not-equal (true on NaN), not ONE. */ 1543 fp_cmp = KIT_CG_FP_UNE; 1544 break; 1545 case TOK_LT: 1546 fp_cmp = KIT_CG_FP_OLT; 1547 break; 1548 case TOK_GT: 1549 fp_cmp = KIT_CG_FP_OGT; 1550 break; 1551 case TOK_LE: 1552 fp_cmp = KIT_CG_FP_OLE; 1553 break; 1554 case TOK_GE: 1555 fp_cmp = KIT_CG_FP_OGE; 1556 break; 1557 default: 1558 return KIT_CG_TYPE_NONE; 1559 } 1560 kit_cg_fp_cmp(p->cg, fp_cmp); 1561 } else if (toy_type_is_intlike(p, ty) || toy_type_is_ptr(p, ty)) { 1562 switch (op) { 1563 case TOK_EQEQ: 1564 cmp = KIT_CG_INT_EQ; 1565 break; 1566 case TOK_NE: 1567 cmp = KIT_CG_INT_NE; 1568 break; 1569 case TOK_LT: 1570 cmp = KIT_CG_INT_LT_S; 1571 break; 1572 case TOK_GT: 1573 cmp = KIT_CG_INT_GT_S; 1574 break; 1575 case TOK_LE: 1576 cmp = KIT_CG_INT_LE_S; 1577 break; 1578 case TOK_GE: 1579 cmp = KIT_CG_INT_GE_S; 1580 break; 1581 default: 1582 return KIT_CG_TYPE_NONE; 1583 } 1584 kit_cg_int_cmp(p->cg, cmp); 1585 } else { 1586 toy_error(p, p->cur.loc, "comparison operands must be scalar"); 1587 return KIT_CG_TYPE_NONE; 1588 } 1589 kit_cg_zext(p->cg, p->int_type); 1590 ty = p->int_type; 1591 toy_note_cg_result_type(p, ty); 1592 } 1593 return ty; 1594 } 1595 1596 static KitCgTypeId toy_parse_expr_shift(ToyParser* p) { 1597 KitCgTypeId ty = toy_parse_expr_cmp(p); 1598 if (ty == KIT_CG_TYPE_NONE) return KIT_CG_TYPE_NONE; 1599 while (p->cur.kind == TOK_SHL || p->cur.kind == TOK_SHR) { 1600 if (p->tail_call_expr) break; 1601 ToyTokenKind op = p->cur.kind; 1602 KitCgIntBinOp binop = (op == TOK_SHL) ? KIT_CG_INT_SHL : KIT_CG_INT_ASHR; 1603 if (!toy_note_expr_island(p, TOY_EXPR_ISLAND_SHIFT)) 1604 return KIT_CG_TYPE_NONE; 1605 toy_parser_advance(p); 1606 KitCgTypeId ty2 = toy_parse_expr_cmp(p); 1607 if (ty2 == KIT_CG_TYPE_NONE) return KIT_CG_TYPE_NONE; 1608 if (toy_reject_tail_call_operand(p)) return KIT_CG_TYPE_NONE; 1609 if (!toy_type_is_promotable_int(p, ty) || 1610 !toy_type_is_promotable_int(p, ty2) || 1611 !toy_promote_binary_int_operands(p, &ty, &ty2)) { 1612 toy_error(p, p->cur.loc, "shift operands must be int"); 1613 return KIT_CG_TYPE_NONE; 1614 } 1615 kit_cg_int_binop(p->cg, binop, 0); 1616 toy_note_cg_result_type(p, ty); 1617 } 1618 return ty; 1619 } 1620 1621 static KitCgTypeId toy_parse_expr_band(ToyParser* p) { 1622 KitCgTypeId ty = toy_parse_expr_shift(p); 1623 if (ty == KIT_CG_TYPE_NONE) return KIT_CG_TYPE_NONE; 1624 while (p->cur.kind == TOK_AMPERSAND) { 1625 if (p->tail_call_expr) break; 1626 if (!toy_note_expr_island(p, TOY_EXPR_ISLAND_BIT_AND)) 1627 return KIT_CG_TYPE_NONE; 1628 toy_parser_advance(p); 1629 KitCgTypeId ty2 = toy_parse_expr_shift(p); 1630 if (ty2 == KIT_CG_TYPE_NONE) return KIT_CG_TYPE_NONE; 1631 if (toy_reject_tail_call_operand(p)) return KIT_CG_TYPE_NONE; 1632 if (!toy_type_is_promotable_int(p, ty) || 1633 !toy_type_is_promotable_int(p, ty2) || 1634 !toy_promote_binary_int_operands(p, &ty, &ty2)) { 1635 toy_error(p, p->cur.loc, "bitwise operands must be int"); 1636 return KIT_CG_TYPE_NONE; 1637 } 1638 kit_cg_int_binop(p->cg, KIT_CG_INT_AND, 0); 1639 toy_note_cg_result_type(p, ty); 1640 } 1641 return ty; 1642 } 1643 1644 static KitCgTypeId toy_parse_expr_bxor(ToyParser* p) { 1645 KitCgTypeId ty = toy_parse_expr_band(p); 1646 if (ty == KIT_CG_TYPE_NONE) return KIT_CG_TYPE_NONE; 1647 while (p->cur.kind == TOK_CARET) { 1648 if (p->tail_call_expr) break; 1649 if (!toy_note_expr_island(p, TOY_EXPR_ISLAND_BIT_XOR)) 1650 return KIT_CG_TYPE_NONE; 1651 toy_parser_advance(p); 1652 KitCgTypeId ty2 = toy_parse_expr_band(p); 1653 if (ty2 == KIT_CG_TYPE_NONE) return KIT_CG_TYPE_NONE; 1654 if (toy_reject_tail_call_operand(p)) return KIT_CG_TYPE_NONE; 1655 if (!toy_type_is_promotable_int(p, ty) || 1656 !toy_type_is_promotable_int(p, ty2) || 1657 !toy_promote_binary_int_operands(p, &ty, &ty2)) { 1658 toy_error(p, p->cur.loc, "bitwise operands must be int"); 1659 return KIT_CG_TYPE_NONE; 1660 } 1661 kit_cg_int_binop(p->cg, KIT_CG_INT_XOR, 0); 1662 toy_note_cg_result_type(p, ty); 1663 } 1664 return ty; 1665 } 1666 1667 static KitCgTypeId toy_parse_expr_bor(ToyParser* p) { 1668 KitCgTypeId ty = toy_parse_expr_bxor(p); 1669 if (ty == KIT_CG_TYPE_NONE) return KIT_CG_TYPE_NONE; 1670 while (p->cur.kind == TOK_PIPE) { 1671 if (p->tail_call_expr) break; 1672 if (!toy_note_expr_island(p, TOY_EXPR_ISLAND_BIT_OR)) 1673 return KIT_CG_TYPE_NONE; 1674 toy_parser_advance(p); 1675 KitCgTypeId ty2 = toy_parse_expr_bxor(p); 1676 if (ty2 == KIT_CG_TYPE_NONE) return KIT_CG_TYPE_NONE; 1677 if (toy_reject_tail_call_operand(p)) return KIT_CG_TYPE_NONE; 1678 if (!toy_type_is_promotable_int(p, ty) || 1679 !toy_type_is_promotable_int(p, ty2) || 1680 !toy_promote_binary_int_operands(p, &ty, &ty2)) { 1681 toy_error(p, p->cur.loc, "bitwise operands must be int"); 1682 return KIT_CG_TYPE_NONE; 1683 } 1684 kit_cg_int_binop(p->cg, KIT_CG_INT_OR, 0); 1685 toy_note_cg_result_type(p, ty); 1686 } 1687 return ty; 1688 } 1689 1690 static KitCgTypeId toy_parse_expr_and(ToyParser* p) { 1691 KitCgTypeId ty = toy_parse_expr_bor(p); 1692 if (ty == KIT_CG_TYPE_NONE) return KIT_CG_TYPE_NONE; 1693 while (p->cur.kind == TOK_AND) { 1694 if (p->tail_call_expr) break; 1695 KitCgTypeId bool_ty = toy_builtin_type(p, KIT_CG_BUILTIN_BOOL); 1696 KitCgLabel false_label; 1697 KitCgLabel end_label; 1698 KitCgLocal result_slot; 1699 if (!toy_note_expr_island(p, TOY_EXPR_ISLAND_LOGIC_AND)) 1700 return KIT_CG_TYPE_NONE; 1701 toy_parser_advance(p); 1702 false_label = kit_cg_label_new(p->cg); 1703 end_label = kit_cg_label_new(p->cg); 1704 result_slot = kit_cg_local(p->cg, bool_ty, toy_slot_attrs(0)); 1705 if (!toy_emit_truthy(p, ty)) return KIT_CG_TYPE_NONE; 1706 kit_cg_branch_false(p->cg, false_label); 1707 ty = toy_parse_expr_bor(p); 1708 if (ty == KIT_CG_TYPE_NONE) return KIT_CG_TYPE_NONE; 1709 if (toy_reject_tail_call_operand(p)) return KIT_CG_TYPE_NONE; 1710 if (!toy_emit_truthy(p, ty)) return KIT_CG_TYPE_NONE; 1711 kit_cg_branch_false(p->cg, false_label); 1712 kit_cg_push_local(p->cg, result_slot); 1713 kit_cg_push_int(p->cg, 1, bool_ty); 1714 kit_cg_store(p->cg, toy_mem_access(p, bool_ty)); 1715 kit_cg_jump(p->cg, end_label); 1716 kit_cg_label_place(p->cg, false_label); 1717 kit_cg_push_local(p->cg, result_slot); 1718 kit_cg_push_int(p->cg, 0, bool_ty); 1719 kit_cg_store(p->cg, toy_mem_access(p, bool_ty)); 1720 kit_cg_label_place(p->cg, end_label); 1721 kit_cg_push_local(p->cg, result_slot); 1722 kit_cg_load(p->cg, toy_mem_access(p, bool_ty)); 1723 ty = bool_ty; 1724 toy_note_cg_result_type(p, ty); 1725 } 1726 return ty; 1727 } 1728 1729 static KitCgTypeId toy_parse_expr_or(ToyParser* p) { 1730 KitCgTypeId ty = toy_parse_expr_and(p); 1731 if (ty == KIT_CG_TYPE_NONE) return KIT_CG_TYPE_NONE; 1732 while (p->cur.kind == TOK_OR) { 1733 if (p->tail_call_expr) break; 1734 KitCgTypeId bool_ty = toy_builtin_type(p, KIT_CG_BUILTIN_BOOL); 1735 KitCgLabel true_label; 1736 KitCgLabel end_label; 1737 KitCgLocal result_slot; 1738 if (!toy_note_expr_island(p, TOY_EXPR_ISLAND_LOGIC_OR)) 1739 return KIT_CG_TYPE_NONE; 1740 toy_parser_advance(p); 1741 true_label = kit_cg_label_new(p->cg); 1742 end_label = kit_cg_label_new(p->cg); 1743 result_slot = kit_cg_local(p->cg, bool_ty, toy_slot_attrs(0)); 1744 if (!toy_emit_truthy(p, ty)) return KIT_CG_TYPE_NONE; 1745 kit_cg_branch_true(p->cg, true_label); 1746 ty = toy_parse_expr_and(p); 1747 if (ty == KIT_CG_TYPE_NONE) return KIT_CG_TYPE_NONE; 1748 if (toy_reject_tail_call_operand(p)) return KIT_CG_TYPE_NONE; 1749 if (!toy_emit_truthy(p, ty)) return KIT_CG_TYPE_NONE; 1750 kit_cg_branch_true(p->cg, true_label); 1751 kit_cg_push_local(p->cg, result_slot); 1752 kit_cg_push_int(p->cg, 0, bool_ty); 1753 kit_cg_store(p->cg, toy_mem_access(p, bool_ty)); 1754 kit_cg_jump(p->cg, end_label); 1755 kit_cg_label_place(p->cg, true_label); 1756 kit_cg_push_local(p->cg, result_slot); 1757 kit_cg_push_int(p->cg, 1, bool_ty); 1758 kit_cg_store(p->cg, toy_mem_access(p, bool_ty)); 1759 kit_cg_label_place(p->cg, end_label); 1760 kit_cg_push_local(p->cg, result_slot); 1761 kit_cg_load(p->cg, toy_mem_access(p, bool_ty)); 1762 ty = bool_ty; 1763 toy_note_cg_result_type(p, ty); 1764 } 1765 return ty; 1766 } 1767 1768 KitCgTypeId toy_parse_expr(ToyParser* p) { 1769 uint32_t saved_island_mask = p->expr_island_mask; 1770 KitCgTypeId ty; 1771 p->expr_island_mask = 0; 1772 ty = toy_parse_expr_or(p); 1773 if (ty != KIT_CG_TYPE_NONE && 1774 (p->cur.kind == TOK_ANDAND || p->cur.kind == TOK_PIPEPIPE)) { 1775 toy_error(p, p->cur.loc, 1776 "legacy logical operator is unsupported; use 'and' or 'or'"); 1777 ty = KIT_CG_TYPE_NONE; 1778 } 1779 p->expr_island_mask = saved_island_mask; 1780 return ty; 1781 }