| ... | ... | @@ -2,6 +2,34 @@ |
| 2 | 2 | #include "analyze.hpp" |
| 3 | 3 | #include "error.hpp" |
| 4 | 4 | |
| 5 | struct EvalVar { |
| 6 | Buf *name; |
| 7 | ConstExprValue value; |
| 8 | }; |
| 9 | |
| 10 | struct EvalScope { |
| 11 | BlockContext *block_context; |
| 12 | ZigList<EvalVar> vars; |
| 13 | }; |
| 14 | |
| 15 | struct EvalFnRoot { |
| 16 | CodeGen *codegen; |
| 17 | FnTableEntry *fn; |
| 18 | AstNode *call_node; |
| 19 | size_t branch_quota; |
| 20 | size_t branches_used; |
| 21 | AstNode *exceeded_quota_node; |
| 22 | bool abort; |
| 23 | }; |
| 24 | |
| 25 | struct EvalFn { |
| 26 | EvalFnRoot *root; |
| 27 | FnTableEntry *fn; |
| 28 | ConstExprValue *return_expr; |
| 29 | ZigList<EvalScope*> scope_stack; |
| 30 | }; |
| 31 | |
| 32 | |
| 5 | 33 | static bool eval_fn_args(EvalFnRoot *efr, FnTableEntry *fn, ConstExprValue *args, ConstExprValue *out_val); |
| 6 | 34 | |
| 7 | 35 | bool const_values_equal(ConstExprValue *a, ConstExprValue *b, TypeTableEntry *type_entry) { |
| ... | ... | @@ -94,9 +122,9 @@ static bool eval_return(EvalFn *ef, AstNode *node, ConstExprValue *out) { |
| 94 | 122 | } |
| 95 | 123 | |
| 96 | 124 | static bool eval_bool_bin_op_bool(bool a, BinOpType bin_op, bool b) { |
| 97 | | if (bin_op == BinOpTypeBoolOr) { |
| 125 | if (bin_op == BinOpTypeBoolOr || bin_op == BinOpTypeAssignBoolOr) { |
| 98 | 126 | return a || b; |
| 99 | | } else if (bin_op == BinOpTypeBoolAnd) { |
| 127 | } else if (bin_op == BinOpTypeBoolAnd || bin_op == BinOpTypeAssignBoolAnd) { |
| 100 | 128 | return a && b; |
| 101 | 129 | } else { |
| 102 | 130 | zig_unreachable(); |
| ... | ... | @@ -180,6 +208,31 @@ static int eval_const_expr_bin_op_bignum(ConstExprValue *op1_val, ConstExprValue |
| 180 | 208 | return 0; |
| 181 | 209 | } |
| 182 | 210 | |
| 211 | bool eval_const_expr_bin_op_handle_errors(EvalFn *ef, AstNode *node, |
| 212 | ConstExprValue *op1_val, TypeTableEntry *op1_type, |
| 213 | BinOpType bin_op, ConstExprValue *op2_val, TypeTableEntry *op2_type, ConstExprValue *out_val) |
| 214 | { |
| 215 | int err; |
| 216 | if ((err = eval_const_expr_bin_op(op1_val, op1_type, bin_op, op2_val, op2_type, out_val))) { |
| 217 | ef->root->abort = true; |
| 218 | if (err == ErrorDivByZero) { |
| 219 | ErrorMsg *msg = add_node_error(ef->root->codegen, ef->root->fn->fn_def_node, |
| 220 | buf_sprintf("function evaluation caused division by zero")); |
| 221 | add_error_note(ef->root->codegen, msg, ef->root->call_node, buf_sprintf("called from here")); |
| 222 | add_error_note(ef->root->codegen, msg, node, buf_sprintf("division by zero here")); |
| 223 | } else if (err == ErrorOverflow) { |
| 224 | ErrorMsg *msg = add_node_error(ef->root->codegen, ef->root->fn->fn_def_node, |
| 225 | buf_sprintf("function evaluation caused overflow")); |
| 226 | add_error_note(ef->root->codegen, msg, ef->root->call_node, buf_sprintf("called from here")); |
| 227 | add_error_note(ef->root->codegen, msg, node, buf_sprintf("overflow occurred here")); |
| 228 | } else { |
| 229 | zig_unreachable(); |
| 230 | } |
| 231 | return true; |
| 232 | } |
| 233 | return false; |
| 234 | } |
| 235 | |
| 183 | 236 | int eval_const_expr_bin_op(ConstExprValue *op1_val, TypeTableEntry *op1_type, |
| 184 | 237 | BinOpType bin_op, ConstExprValue *op2_val, TypeTableEntry *op2_type, ConstExprValue *out_val) |
| 185 | 238 | { |
| ... | ... | @@ -190,25 +243,12 @@ int eval_const_expr_bin_op(ConstExprValue *op1_val, TypeTableEntry *op1_type, |
| 190 | 243 | |
| 191 | 244 | switch (bin_op) { |
| 192 | 245 | case BinOpTypeAssign: |
| 193 | | case BinOpTypeAssignTimes: |
| 194 | | case BinOpTypeAssignTimesWrap: |
| 195 | | case BinOpTypeAssignDiv: |
| 196 | | case BinOpTypeAssignMod: |
| 197 | | case BinOpTypeAssignPlus: |
| 198 | | case BinOpTypeAssignPlusWrap: |
| 199 | | case BinOpTypeAssignMinus: |
| 200 | | case BinOpTypeAssignMinusWrap: |
| 201 | | case BinOpTypeAssignBitShiftLeft: |
| 202 | | case BinOpTypeAssignBitShiftLeftWrap: |
| 203 | | case BinOpTypeAssignBitShiftRight: |
| 204 | | case BinOpTypeAssignBitAnd: |
| 205 | | case BinOpTypeAssignBitXor: |
| 206 | | case BinOpTypeAssignBitOr: |
| 207 | | case BinOpTypeAssignBoolAnd: |
| 208 | | case BinOpTypeAssignBoolOr: |
| 209 | | zig_unreachable(); |
| 246 | *out_val = *op2_val; |
| 247 | return 0; |
| 210 | 248 | case BinOpTypeBoolOr: |
| 211 | 249 | case BinOpTypeBoolAnd: |
| 250 | case BinOpTypeAssignBoolAnd: |
| 251 | case BinOpTypeAssignBoolOr: |
| 212 | 252 | assert(op1_type->id == TypeTableEntryIdBool); |
| 213 | 253 | assert(op2_type->id == TypeTableEntryIdBool); |
| 214 | 254 | out_val->data.x_bool = eval_bool_bin_op_bool(op1_val->data.x_bool, bin_op, op2_val->data.x_bool); |
| ... | ... | @@ -264,30 +304,43 @@ int eval_const_expr_bin_op(ConstExprValue *op1_val, TypeTableEntry *op1_type, |
| 264 | 304 | return 0; |
| 265 | 305 | } |
| 266 | 306 | case BinOpTypeAdd: |
| 307 | case BinOpTypeAssignPlus: |
| 267 | 308 | return eval_const_expr_bin_op_bignum(op1_val, op2_val, out_val, bignum_add, op1_type, false); |
| 268 | 309 | case BinOpTypeAddWrap: |
| 310 | case BinOpTypeAssignPlusWrap: |
| 269 | 311 | return eval_const_expr_bin_op_bignum(op1_val, op2_val, out_val, bignum_add, op1_type, true); |
| 270 | 312 | case BinOpTypeBinOr: |
| 313 | case BinOpTypeAssignBitOr: |
| 271 | 314 | return eval_const_expr_bin_op_bignum(op1_val, op2_val, out_val, bignum_or, op1_type, false); |
| 272 | 315 | case BinOpTypeBinXor: |
| 316 | case BinOpTypeAssignBitXor: |
| 273 | 317 | return eval_const_expr_bin_op_bignum(op1_val, op2_val, out_val, bignum_xor, op1_type, false); |
| 274 | 318 | case BinOpTypeBinAnd: |
| 319 | case BinOpTypeAssignBitAnd: |
| 275 | 320 | return eval_const_expr_bin_op_bignum(op1_val, op2_val, out_val, bignum_and, op1_type, false); |
| 276 | 321 | case BinOpTypeBitShiftLeft: |
| 322 | case BinOpTypeAssignBitShiftLeft: |
| 277 | 323 | return eval_const_expr_bin_op_bignum(op1_val, op2_val, out_val, bignum_shl, op1_type, false); |
| 278 | 324 | case BinOpTypeBitShiftLeftWrap: |
| 325 | case BinOpTypeAssignBitShiftLeftWrap: |
| 279 | 326 | return eval_const_expr_bin_op_bignum(op1_val, op2_val, out_val, bignum_shl, op1_type, true); |
| 280 | 327 | case BinOpTypeBitShiftRight: |
| 328 | case BinOpTypeAssignBitShiftRight: |
| 281 | 329 | return eval_const_expr_bin_op_bignum(op1_val, op2_val, out_val, bignum_shr, op1_type, false); |
| 282 | 330 | case BinOpTypeSub: |
| 331 | case BinOpTypeAssignMinus: |
| 283 | 332 | return eval_const_expr_bin_op_bignum(op1_val, op2_val, out_val, bignum_sub, op1_type, false); |
| 284 | 333 | case BinOpTypeSubWrap: |
| 334 | case BinOpTypeAssignMinusWrap: |
| 285 | 335 | return eval_const_expr_bin_op_bignum(op1_val, op2_val, out_val, bignum_sub, op1_type, true); |
| 286 | 336 | case BinOpTypeMult: |
| 337 | case BinOpTypeAssignTimes: |
| 287 | 338 | return eval_const_expr_bin_op_bignum(op1_val, op2_val, out_val, bignum_mul, op1_type, false); |
| 288 | 339 | case BinOpTypeMultWrap: |
| 340 | case BinOpTypeAssignTimesWrap: |
| 289 | 341 | return eval_const_expr_bin_op_bignum(op1_val, op2_val, out_val, bignum_mul, op1_type, true); |
| 290 | 342 | case BinOpTypeDiv: |
| 343 | case BinOpTypeAssignDiv: |
| 291 | 344 | { |
| 292 | 345 | bool is_int = false; |
| 293 | 346 | bool is_float = false; |
| ... | ... | @@ -309,6 +362,7 @@ int eval_const_expr_bin_op(ConstExprValue *op1_val, TypeTableEntry *op1_type, |
| 309 | 362 | } |
| 310 | 363 | } |
| 311 | 364 | case BinOpTypeMod: |
| 365 | case BinOpTypeAssignMod: |
| 312 | 366 | return eval_const_expr_bin_op_bignum(op1_val, op2_val, out_val, bignum_mod, op1_type, false); |
| 313 | 367 | case BinOpTypeUnwrapMaybe: |
| 314 | 368 | zig_panic("TODO"); |
| ... | ... | @@ -320,13 +374,66 @@ int eval_const_expr_bin_op(ConstExprValue *op1_val, TypeTableEntry *op1_type, |
| 320 | 374 | zig_unreachable(); |
| 321 | 375 | } |
| 322 | 376 | |
| 323 | | static bool eval_bin_op_expr(EvalFn *ef, AstNode *node, ConstExprValue *out_val) { |
| 324 | | assert(node->type == NodeTypeBinOpExpr); |
| 377 | static EvalVar *find_var(EvalFn *ef, Buf *name) { |
| 378 | size_t scope_index = ef->scope_stack.length - 1; |
| 379 | while (scope_index != SIZE_MAX) { |
| 380 | EvalScope *scope = ef->scope_stack.at(scope_index); |
| 381 | for (size_t var_i = 0; var_i < scope->vars.length; var_i += 1) { |
| 382 | EvalVar *var = &scope->vars.at(var_i); |
| 383 | if (buf_eql_buf(var->name, name)) { |
| 384 | return var; |
| 385 | } |
| 386 | } |
| 387 | scope_index -= 1; |
| 388 | } |
| 325 | 389 | |
| 390 | return nullptr; |
| 391 | } |
| 392 | |
| 393 | static bool eval_get_lvalue(EvalFn *ef, AstNode *node, ConstExprValue **lvalue) { |
| 394 | if (node->type == NodeTypeSymbol) { |
| 395 | Buf *name = node->data.symbol_expr.symbol; |
| 396 | EvalVar *var = find_var(ef, name); |
| 397 | assert(var); |
| 398 | *lvalue = &var->value; |
| 399 | } else { |
| 400 | zig_panic("TODO eval other lvalue types"); |
| 401 | } |
| 402 | return false; |
| 403 | } |
| 404 | |
| 405 | static bool eval_bin_op_assign(EvalFn *ef, AstNode *node, ConstExprValue *out_val) { |
| 326 | 406 | AstNode *op1 = node->data.bin_op_expr.op1; |
| 327 | 407 | AstNode *op2 = node->data.bin_op_expr.op2; |
| 328 | 408 | BinOpType bin_op = node->data.bin_op_expr.bin_op; |
| 329 | 409 | |
| 410 | TypeTableEntry *op2_type = get_resolved_expr(op2)->type_entry; |
| 411 | assert(op2_type); |
| 412 | |
| 413 | ConstExprValue *assign_result_val; |
| 414 | if (eval_get_lvalue(ef, op1, &assign_result_val)) return true; |
| 415 | |
| 416 | ConstExprValue op1_val = *assign_result_val; |
| 417 | |
| 418 | ConstExprValue op2_val = {0}; |
| 419 | if (eval_expr(ef, op2, &op2_val)) return true; |
| 420 | |
| 421 | if (eval_const_expr_bin_op_handle_errors(ef, node, &op1_val, op2_type, bin_op, &op2_val, op2_type, |
| 422 | assign_result_val)) |
| 423 | { |
| 424 | return true; |
| 425 | } |
| 426 | |
| 427 | out_val->ok = true; |
| 428 | out_val->depends_on_compile_var = false; |
| 429 | return false; |
| 430 | } |
| 431 | |
| 432 | static bool eval_bin_op_expr(EvalFn *ef, AstNode *node, ConstExprValue *out_val) { |
| 433 | assert(node->type == NodeTypeBinOpExpr); |
| 434 | |
| 435 | BinOpType bin_op = node->data.bin_op_expr.bin_op; |
| 436 | |
| 330 | 437 | switch (bin_op) { |
| 331 | 438 | case BinOpTypeAssign: |
| 332 | 439 | case BinOpTypeAssignTimes: |
| ... | ... | @@ -345,7 +452,7 @@ static bool eval_bin_op_expr(EvalFn *ef, AstNode *node, ConstExprValue *out_val) |
| 345 | 452 | case BinOpTypeAssignBitOr: |
| 346 | 453 | case BinOpTypeAssignBoolAnd: |
| 347 | 454 | case BinOpTypeAssignBoolOr: |
| 348 | | zig_panic("TODO"); |
| 455 | return eval_bin_op_assign(ef, node, out_val); |
| 349 | 456 | case BinOpTypeBoolOr: |
| 350 | 457 | case BinOpTypeBoolAnd: |
| 351 | 458 | case BinOpTypeCmpEq: |
| ... | ... | @@ -376,6 +483,10 @@ static bool eval_bin_op_expr(EvalFn *ef, AstNode *node, ConstExprValue *out_val) |
| 376 | 483 | zig_unreachable(); |
| 377 | 484 | } |
| 378 | 485 | |
| 486 | AstNode *op1 = node->data.bin_op_expr.op1; |
| 487 | AstNode *op2 = node->data.bin_op_expr.op2; |
| 488 | |
| 489 | |
| 379 | 490 | TypeTableEntry *op1_type = get_resolved_expr(op1)->type_entry; |
| 380 | 491 | TypeTableEntry *op2_type = get_resolved_expr(op2)->type_entry; |
| 381 | 492 | |
| ... | ... | @@ -388,22 +499,7 @@ static bool eval_bin_op_expr(EvalFn *ef, AstNode *node, ConstExprValue *out_val) |
| 388 | 499 | ConstExprValue op2_val = {0}; |
| 389 | 500 | if (eval_expr(ef, op2, &op2_val)) return true; |
| 390 | 501 | |
| 391 | | int err; |
| 392 | | if ((err = eval_const_expr_bin_op(&op1_val, op1_type, bin_op, &op2_val, op2_type, out_val))) { |
| 393 | | ef->root->abort = true; |
| 394 | | if (err == ErrorDivByZero) { |
| 395 | | ErrorMsg *msg = add_node_error(ef->root->codegen, ef->root->fn->fn_def_node, |
| 396 | | buf_sprintf("function evaluation caused division by zero")); |
| 397 | | add_error_note(ef->root->codegen, msg, ef->root->call_node, buf_sprintf("called from here")); |
| 398 | | add_error_note(ef->root->codegen, msg, node, buf_sprintf("division by zero here")); |
| 399 | | } else if (err == ErrorOverflow) { |
| 400 | | ErrorMsg *msg = add_node_error(ef->root->codegen, ef->root->fn->fn_def_node, |
| 401 | | buf_sprintf("function evaluation caused overflow")); |
| 402 | | add_error_note(ef->root->codegen, msg, ef->root->call_node, buf_sprintf("called from here")); |
| 403 | | add_error_note(ef->root->codegen, msg, node, buf_sprintf("overflow occurred here")); |
| 404 | | } else { |
| 405 | | zig_unreachable(); |
| 406 | | } |
| 502 | if (eval_const_expr_bin_op_handle_errors(ef, node, &op1_val, op1_type, bin_op, &op2_val, op2_type, out_val)) { |
| 407 | 503 | return true; |
| 408 | 504 | } |
| 409 | 505 | |
| ... | ... | @@ -412,22 +508,6 @@ static bool eval_bin_op_expr(EvalFn *ef, AstNode *node, ConstExprValue *out_val) |
| 412 | 508 | return false; |
| 413 | 509 | } |
| 414 | 510 | |
| 415 | | static EvalVar *find_var(EvalFn *ef, Buf *name) { |
| 416 | | size_t scope_index = ef->scope_stack.length - 1; |
| 417 | | while (scope_index != SIZE_MAX) { |
| 418 | | EvalScope *scope = ef->scope_stack.at(scope_index); |
| 419 | | for (size_t var_i = 0; var_i < scope->vars.length; var_i += 1) { |
| 420 | | EvalVar *var = &scope->vars.at(var_i); |
| 421 | | if (buf_eql_buf(var->name, name)) { |
| 422 | | return var; |
| 423 | | } |
| 424 | | } |
| 425 | | scope_index -= 1; |
| 426 | | } |
| 427 | | |
| 428 | | return nullptr; |
| 429 | | } |
| 430 | | |
| 431 | 511 | static bool eval_symbol_expr(EvalFn *ef, AstNode *node, ConstExprValue *out_val) { |
| 432 | 512 | assert(node->type == NodeTypeSymbol); |
| 433 | 513 | |
| ... | ... | @@ -456,7 +536,7 @@ static bool eval_container_init_expr(EvalFn *ef, AstNode *node, ConstExprValue * |
| 456 | 536 | ContainerInitKind kind = container_init_expr->kind; |
| 457 | 537 | |
| 458 | 538 | if (container_init_expr->enum_type) { |
| 459 | | zig_panic("TODO"); |
| 539 | zig_panic("TODO eval enum init"); |
| 460 | 540 | } |
| 461 | 541 | |
| 462 | 542 | TypeTableEntry *container_type = resolve_expr_type(container_init_expr->type); |
| ... | ... | @@ -514,7 +594,7 @@ static bool eval_container_init_expr(EvalFn *ef, AstNode *node, ConstExprValue * |
| 514 | 594 | elem_val->depends_on_compile_var; |
| 515 | 595 | } |
| 516 | 596 | } else { |
| 517 | | zig_panic("TODO"); |
| 597 | zig_panic("TODO init more container kinds"); |
| 518 | 598 | } |
| 519 | 599 | |
| 520 | 600 | |
| ... | ... | @@ -874,7 +954,7 @@ static bool eval_fn_call_builtin(EvalFn *ef, AstNode *node, ConstExprValue *out_ |
| 874 | 954 | case BuiltinFnIdEmbedFile: |
| 875 | 955 | case BuiltinFnIdCmpExchange: |
| 876 | 956 | case BuiltinFnIdTruncate: |
| 877 | | zig_panic("TODO"); |
| 957 | zig_panic("TODO builtin function"); |
| 878 | 958 | case BuiltinFnIdBreakpoint: |
| 879 | 959 | case BuiltinFnIdInvalid: |
| 880 | 960 | case BuiltinFnIdFrameAddress: |
| ... | ... | @@ -909,7 +989,7 @@ static bool eval_fn_call_expr(EvalFn *ef, AstNode *node, ConstExprValue *out_val |
| 909 | 989 | if (fn_ref_expr->type == NodeTypeFieldAccessExpr && |
| 910 | 990 | fn_ref_expr->data.field_access_expr.is_member_fn) |
| 911 | 991 | { |
| 912 | | zig_panic("TODO"); |
| 992 | zig_panic("TODO field access member fn"); |
| 913 | 993 | } |
| 914 | 994 | |
| 915 | 995 | if (!fn_table_entry) { |
| ... | ... | @@ -941,7 +1021,7 @@ static bool eval_field_access_expr(EvalFn *ef, AstNode *node, ConstExprValue *ou |
| 941 | 1021 | if (struct_type->id == TypeTableEntryIdArray) { |
| 942 | 1022 | Buf *name = node->data.field_access_expr.field_name; |
| 943 | 1023 | assert(buf_eql_str(name, "len")); |
| 944 | | zig_panic("TODO"); |
| 1024 | zig_panic("TODO field access array"); |
| 945 | 1025 | } else if (struct_type->id == TypeTableEntryIdStruct || (struct_type->id == TypeTableEntryIdPointer && |
| 946 | 1026 | struct_type->data.pointer.child_type->id == TypeTableEntryIdStruct)) |
| 947 | 1027 | { |
| ... | ... | @@ -954,17 +1034,17 @@ static bool eval_field_access_expr(EvalFn *ef, AstNode *node, ConstExprValue *ou |
| 954 | 1034 | *out_val = *field_value; |
| 955 | 1035 | assert(out_val->ok); |
| 956 | 1036 | } else { |
| 957 | | zig_panic("TODO"); |
| 1037 | zig_panic("TODO field access struct"); |
| 958 | 1038 | } |
| 959 | 1039 | } else if (struct_type->id == TypeTableEntryIdMetaType) { |
| 960 | 1040 | TypeTableEntry *child_type = resolve_expr_type(struct_expr); |
| 961 | 1041 | if (child_type->id == TypeTableEntryIdPureError) { |
| 962 | 1042 | *out_val = get_resolved_expr(node)->const_val; |
| 963 | 1043 | } else { |
| 964 | | zig_panic("TODO"); |
| 1044 | zig_panic("TODO field access meta type"); |
| 965 | 1045 | } |
| 966 | 1046 | } else if (struct_type->id == TypeTableEntryIdNamespace) { |
| 967 | | zig_panic("TODO"); |
| 1047 | zig_panic("TODO field access namespace"); |
| 968 | 1048 | } else { |
| 969 | 1049 | zig_unreachable(); |
| 970 | 1050 | } |
| ... | ... | @@ -989,7 +1069,7 @@ static bool eval_for_expr(EvalFn *ef, AstNode *node, ConstExprValue *out_val) { |
| 989 | 1069 | Buf *elem_var_name = elem_node->data.symbol_expr.symbol; |
| 990 | 1070 | |
| 991 | 1071 | if (node->data.for_expr.elem_is_ptr) { |
| 992 | | zig_panic("TODO"); |
| 1072 | zig_panic("TODO for elem is ptr"); |
| 993 | 1073 | } |
| 994 | 1074 | |
| 995 | 1075 | Buf *index_var_name = nullptr; |
| ... | ... | @@ -1062,7 +1142,7 @@ static bool eval_array_access_expr(EvalFn *ef, AstNode *node, ConstExprValue *ou |
| 1062 | 1142 | |
| 1063 | 1143 | if (array_type->id == TypeTableEntryIdPointer) { |
| 1064 | 1144 | if (index_int >= array_val.data.x_ptr.len) { |
| 1065 | | zig_panic("TODO"); |
| 1145 | zig_panic("TODO array access pointer"); |
| 1066 | 1146 | } |
| 1067 | 1147 | *out_val = *array_val.data.x_ptr.ptr[index_int]; |
| 1068 | 1148 | } else if (array_type->id == TypeTableEntryIdStruct) { |
| ... | ... | @@ -1071,7 +1151,7 @@ static bool eval_array_access_expr(EvalFn *ef, AstNode *node, ConstExprValue *ou |
| 1071 | 1151 | ConstExprValue *len_value = array_val.data.x_struct.fields[1]; |
| 1072 | 1152 | uint64_t len_int = len_value->data.x_bignum.data.x_uint; |
| 1073 | 1153 | if (index_int >= len_int) { |
| 1074 | | zig_panic("TODO"); |
| 1154 | zig_panic("TODO array access slice"); |
| 1075 | 1155 | } |
| 1076 | 1156 | |
| 1077 | 1157 | ConstExprValue *ptr_value = array_val.data.x_struct.fields[0]; |
| ... | ... | @@ -1079,7 +1159,7 @@ static bool eval_array_access_expr(EvalFn *ef, AstNode *node, ConstExprValue *ou |
| 1079 | 1159 | } else if (array_type->id == TypeTableEntryIdArray) { |
| 1080 | 1160 | uint64_t array_len = array_type->data.array.len; |
| 1081 | 1161 | if (index_int >= array_len) { |
| 1082 | | zig_panic("TODO"); |
| 1162 | zig_panic("TODO array access array"); |
| 1083 | 1163 | } |
| 1084 | 1164 | *out_val = *array_val.data.x_array.fields[index_int]; |
| 1085 | 1165 | } else { |
| ... | ... | @@ -1152,7 +1232,7 @@ static bool eval_prefix_op_expr(EvalFn *ef, AstNode *node, ConstExprValue *out_v |
| 1152 | 1232 | return true; |
| 1153 | 1233 | } |
| 1154 | 1234 | } else if (expr_type->id == TypeTableEntryIdFloat) { |
| 1155 | | zig_panic("TODO"); |
| 1235 | zig_panic("TODO prefix op on floats"); |
| 1156 | 1236 | } else { |
| 1157 | 1237 | zig_unreachable(); |
| 1158 | 1238 | } |
| ... | ... | @@ -1162,7 +1242,7 @@ static bool eval_prefix_op_expr(EvalFn *ef, AstNode *node, ConstExprValue *out_v |
| 1162 | 1242 | case PrefixOpError: |
| 1163 | 1243 | case PrefixOpUnwrapError: |
| 1164 | 1244 | case PrefixOpUnwrapMaybe: |
| 1165 | | zig_panic("TODO"); |
| 1245 | zig_panic("TODO more prefix operations"); |
| 1166 | 1246 | case PrefixOpInvalid: |
| 1167 | 1247 | zig_unreachable(); |
| 1168 | 1248 | } |
| ... | ... | @@ -1308,7 +1388,7 @@ static bool eval_expr(EvalFn *ef, AstNode *node, ConstExprValue *out) { |
| 1308 | 1388 | case NodeTypeErrorType: |
| 1309 | 1389 | case NodeTypeTypeLiteral: |
| 1310 | 1390 | case NodeTypeVarLiteral: |
| 1311 | | zig_panic("TODO"); |
| 1391 | zig_panic("TODO expr node"); |
| 1312 | 1392 | case NodeTypeRoot: |
| 1313 | 1393 | case NodeTypeFnProto: |
| 1314 | 1394 | case NodeTypeFnDef: |