| ... | @@ -2,6 +2,34 @@ | ... | @@ -2,6 +2,34 @@ |
| 2 | #include "analyze.hpp" | 2 | #include "analyze.hpp" |
| 3 | #include "error.hpp" | 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 | static bool eval_fn_args(EvalFnRoot *efr, FnTableEntry *fn, ConstExprValue *args, ConstExprValue *out_val); | 33 | static bool eval_fn_args(EvalFnRoot *efr, FnTableEntry *fn, ConstExprValue *args, ConstExprValue *out_val); |
| 6 | | 34 | |
| 7 | bool const_values_equal(ConstExprValue *a, ConstExprValue *b, TypeTableEntry *type_entry) { | 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,9 +122,9 @@ static bool eval_return(EvalFn *ef, AstNode *node, ConstExprValue *out) { |
| 94 | } | 122 | } |
| 95 | | 123 | |
| 96 | static bool eval_bool_bin_op_bool(bool a, BinOpType bin_op, bool b) { | 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 | return a || b; | 126 | return a || b; |
| 99 | } else if (bin_op == BinOpTypeBoolAnd) { | 127 | } else if (bin_op == BinOpTypeBoolAnd || bin_op == BinOpTypeAssignBoolAnd) { |
| 100 | return a && b; | 128 | return a && b; |
| 101 | } else { | 129 | } else { |
| 102 | zig_unreachable(); | 130 | zig_unreachable(); |
| ... | @@ -180,6 +208,31 @@ static int eval_const_expr_bin_op_bignum(ConstExprValue *op1_val, ConstExprValue | ... | @@ -180,6 +208,31 @@ static int eval_const_expr_bin_op_bignum(ConstExprValue *op1_val, ConstExprValue |
| 180 | return 0; | 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 | int eval_const_expr_bin_op(ConstExprValue *op1_val, TypeTableEntry *op1_type, | 236 | int eval_const_expr_bin_op(ConstExprValue *op1_val, TypeTableEntry *op1_type, |
| 184 | BinOpType bin_op, ConstExprValue *op2_val, TypeTableEntry *op2_type, ConstExprValue *out_val) | 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,25 +243,12 @@ int eval_const_expr_bin_op(ConstExprValue *op1_val, TypeTableEntry *op1_type, |
| 190 | | 243 | |
| 191 | switch (bin_op) { | 244 | switch (bin_op) { |
| 192 | case BinOpTypeAssign: | 245 | case BinOpTypeAssign: |
| 193 | case BinOpTypeAssignTimes: | 246 | *out_val = *op2_val; |
| 194 | case BinOpTypeAssignTimesWrap: | 247 | return 0; |
| 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(); | | |
| 210 | case BinOpTypeBoolOr: | 248 | case BinOpTypeBoolOr: |
| 211 | case BinOpTypeBoolAnd: | 249 | case BinOpTypeBoolAnd: |
| | 250 | case BinOpTypeAssignBoolAnd: |
| | 251 | case BinOpTypeAssignBoolOr: |
| 212 | assert(op1_type->id == TypeTableEntryIdBool); | 252 | assert(op1_type->id == TypeTableEntryIdBool); |
| 213 | assert(op2_type->id == TypeTableEntryIdBool); | 253 | assert(op2_type->id == TypeTableEntryIdBool); |
| 214 | out_val->data.x_bool = eval_bool_bin_op_bool(op1_val->data.x_bool, bin_op, op2_val->data.x_bool); | 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,30 +304,43 @@ int eval_const_expr_bin_op(ConstExprValue *op1_val, TypeTableEntry *op1_type, |
| 264 | return 0; | 304 | return 0; |
| 265 | } | 305 | } |
| 266 | case BinOpTypeAdd: | 306 | case BinOpTypeAdd: |
| | 307 | case BinOpTypeAssignPlus: |
| 267 | return eval_const_expr_bin_op_bignum(op1_val, op2_val, out_val, bignum_add, op1_type, false); | 308 | return eval_const_expr_bin_op_bignum(op1_val, op2_val, out_val, bignum_add, op1_type, false); |
| 268 | case BinOpTypeAddWrap: | 309 | case BinOpTypeAddWrap: |
| | 310 | case BinOpTypeAssignPlusWrap: |
| 269 | return eval_const_expr_bin_op_bignum(op1_val, op2_val, out_val, bignum_add, op1_type, true); | 311 | return eval_const_expr_bin_op_bignum(op1_val, op2_val, out_val, bignum_add, op1_type, true); |
| 270 | case BinOpTypeBinOr: | 312 | case BinOpTypeBinOr: |
| | 313 | case BinOpTypeAssignBitOr: |
| 271 | return eval_const_expr_bin_op_bignum(op1_val, op2_val, out_val, bignum_or, op1_type, false); | 314 | return eval_const_expr_bin_op_bignum(op1_val, op2_val, out_val, bignum_or, op1_type, false); |
| 272 | case BinOpTypeBinXor: | 315 | case BinOpTypeBinXor: |
| | 316 | case BinOpTypeAssignBitXor: |
| 273 | return eval_const_expr_bin_op_bignum(op1_val, op2_val, out_val, bignum_xor, op1_type, false); | 317 | return eval_const_expr_bin_op_bignum(op1_val, op2_val, out_val, bignum_xor, op1_type, false); |
| 274 | case BinOpTypeBinAnd: | 318 | case BinOpTypeBinAnd: |
| | 319 | case BinOpTypeAssignBitAnd: |
| 275 | return eval_const_expr_bin_op_bignum(op1_val, op2_val, out_val, bignum_and, op1_type, false); | 320 | return eval_const_expr_bin_op_bignum(op1_val, op2_val, out_val, bignum_and, op1_type, false); |
| 276 | case BinOpTypeBitShiftLeft: | 321 | case BinOpTypeBitShiftLeft: |
| | 322 | case BinOpTypeAssignBitShiftLeft: |
| 277 | return eval_const_expr_bin_op_bignum(op1_val, op2_val, out_val, bignum_shl, op1_type, false); | 323 | return eval_const_expr_bin_op_bignum(op1_val, op2_val, out_val, bignum_shl, op1_type, false); |
| 278 | case BinOpTypeBitShiftLeftWrap: | 324 | case BinOpTypeBitShiftLeftWrap: |
| | 325 | case BinOpTypeAssignBitShiftLeftWrap: |
| 279 | return eval_const_expr_bin_op_bignum(op1_val, op2_val, out_val, bignum_shl, op1_type, true); | 326 | return eval_const_expr_bin_op_bignum(op1_val, op2_val, out_val, bignum_shl, op1_type, true); |
| 280 | case BinOpTypeBitShiftRight: | 327 | case BinOpTypeBitShiftRight: |
| | 328 | case BinOpTypeAssignBitShiftRight: |
| 281 | return eval_const_expr_bin_op_bignum(op1_val, op2_val, out_val, bignum_shr, op1_type, false); | 329 | return eval_const_expr_bin_op_bignum(op1_val, op2_val, out_val, bignum_shr, op1_type, false); |
| 282 | case BinOpTypeSub: | 330 | case BinOpTypeSub: |
| | 331 | case BinOpTypeAssignMinus: |
| 283 | return eval_const_expr_bin_op_bignum(op1_val, op2_val, out_val, bignum_sub, op1_type, false); | 332 | return eval_const_expr_bin_op_bignum(op1_val, op2_val, out_val, bignum_sub, op1_type, false); |
| 284 | case BinOpTypeSubWrap: | 333 | case BinOpTypeSubWrap: |
| | 334 | case BinOpTypeAssignMinusWrap: |
| 285 | return eval_const_expr_bin_op_bignum(op1_val, op2_val, out_val, bignum_sub, op1_type, true); | 335 | return eval_const_expr_bin_op_bignum(op1_val, op2_val, out_val, bignum_sub, op1_type, true); |
| 286 | case BinOpTypeMult: | 336 | case BinOpTypeMult: |
| | 337 | case BinOpTypeAssignTimes: |
| 287 | return eval_const_expr_bin_op_bignum(op1_val, op2_val, out_val, bignum_mul, op1_type, false); | 338 | return eval_const_expr_bin_op_bignum(op1_val, op2_val, out_val, bignum_mul, op1_type, false); |
| 288 | case BinOpTypeMultWrap: | 339 | case BinOpTypeMultWrap: |
| | 340 | case BinOpTypeAssignTimesWrap: |
| 289 | return eval_const_expr_bin_op_bignum(op1_val, op2_val, out_val, bignum_mul, op1_type, true); | 341 | return eval_const_expr_bin_op_bignum(op1_val, op2_val, out_val, bignum_mul, op1_type, true); |
| 290 | case BinOpTypeDiv: | 342 | case BinOpTypeDiv: |
| | 343 | case BinOpTypeAssignDiv: |
| 291 | { | 344 | { |
| 292 | bool is_int = false; | 345 | bool is_int = false; |
| 293 | bool is_float = false; | 346 | bool is_float = false; |
| ... | @@ -309,6 +362,7 @@ int eval_const_expr_bin_op(ConstExprValue *op1_val, TypeTableEntry *op1_type, | ... | @@ -309,6 +362,7 @@ int eval_const_expr_bin_op(ConstExprValue *op1_val, TypeTableEntry *op1_type, |
| 309 | } | 362 | } |
| 310 | } | 363 | } |
| 311 | case BinOpTypeMod: | 364 | case BinOpTypeMod: |
| | 365 | case BinOpTypeAssignMod: |
| 312 | return eval_const_expr_bin_op_bignum(op1_val, op2_val, out_val, bignum_mod, op1_type, false); | 366 | return eval_const_expr_bin_op_bignum(op1_val, op2_val, out_val, bignum_mod, op1_type, false); |
| 313 | case BinOpTypeUnwrapMaybe: | 367 | case BinOpTypeUnwrapMaybe: |
| 314 | zig_panic("TODO"); | 368 | zig_panic("TODO"); |
| ... | @@ -320,13 +374,66 @@ int eval_const_expr_bin_op(ConstExprValue *op1_val, TypeTableEntry *op1_type, | ... | @@ -320,13 +374,66 @@ int eval_const_expr_bin_op(ConstExprValue *op1_val, TypeTableEntry *op1_type, |
| 320 | zig_unreachable(); | 374 | zig_unreachable(); |
| 321 | } | 375 | } |
| 322 | | 376 | |
| 323 | static bool eval_bin_op_expr(EvalFn *ef, AstNode *node, ConstExprValue *out_val) { | 377 | static EvalVar *find_var(EvalFn *ef, Buf *name) { |
| 324 | assert(node->type == NodeTypeBinOpExpr); | 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 | AstNode *op1 = node->data.bin_op_expr.op1; | 406 | AstNode *op1 = node->data.bin_op_expr.op1; |
| 327 | AstNode *op2 = node->data.bin_op_expr.op2; | 407 | AstNode *op2 = node->data.bin_op_expr.op2; |
| 328 | BinOpType bin_op = node->data.bin_op_expr.bin_op; | 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 | switch (bin_op) { | 437 | switch (bin_op) { |
| 331 | case BinOpTypeAssign: | 438 | case BinOpTypeAssign: |
| 332 | case BinOpTypeAssignTimes: | 439 | case BinOpTypeAssignTimes: |
| ... | @@ -345,7 +452,7 @@ static bool eval_bin_op_expr(EvalFn *ef, AstNode *node, ConstExprValue *out_val) | ... | @@ -345,7 +452,7 @@ static bool eval_bin_op_expr(EvalFn *ef, AstNode *node, ConstExprValue *out_val) |
| 345 | case BinOpTypeAssignBitOr: | 452 | case BinOpTypeAssignBitOr: |
| 346 | case BinOpTypeAssignBoolAnd: | 453 | case BinOpTypeAssignBoolAnd: |
| 347 | case BinOpTypeAssignBoolOr: | 454 | case BinOpTypeAssignBoolOr: |
| 348 | zig_panic("TODO"); | 455 | return eval_bin_op_assign(ef, node, out_val); |
| 349 | case BinOpTypeBoolOr: | 456 | case BinOpTypeBoolOr: |
| 350 | case BinOpTypeBoolAnd: | 457 | case BinOpTypeBoolAnd: |
| 351 | case BinOpTypeCmpEq: | 458 | case BinOpTypeCmpEq: |
| ... | @@ -376,6 +483,10 @@ static bool eval_bin_op_expr(EvalFn *ef, AstNode *node, ConstExprValue *out_val) | ... | @@ -376,6 +483,10 @@ static bool eval_bin_op_expr(EvalFn *ef, AstNode *node, ConstExprValue *out_val) |
| 376 | zig_unreachable(); | 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 | TypeTableEntry *op1_type = get_resolved_expr(op1)->type_entry; | 490 | TypeTableEntry *op1_type = get_resolved_expr(op1)->type_entry; |
| 380 | TypeTableEntry *op2_type = get_resolved_expr(op2)->type_entry; | 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,22 +499,7 @@ static bool eval_bin_op_expr(EvalFn *ef, AstNode *node, ConstExprValue *out_val) |
| 388 | ConstExprValue op2_val = {0}; | 499 | ConstExprValue op2_val = {0}; |
| 389 | if (eval_expr(ef, op2, &op2_val)) return true; | 500 | if (eval_expr(ef, op2, &op2_val)) return true; |
| 390 | | 501 | |
| 391 | int err; | 502 | if (eval_const_expr_bin_op_handle_errors(ef, node, &op1_val, op1_type, bin_op, &op2_val, op2_type, out_val)) { |
| 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 | } | | |
| 407 | return true; | 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,22 +508,6 @@ static bool eval_bin_op_expr(EvalFn *ef, AstNode *node, ConstExprValue *out_val) |
| 412 | return false; | 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 | static bool eval_symbol_expr(EvalFn *ef, AstNode *node, ConstExprValue *out_val) { | 511 | static bool eval_symbol_expr(EvalFn *ef, AstNode *node, ConstExprValue *out_val) { |
| 432 | assert(node->type == NodeTypeSymbol); | 512 | assert(node->type == NodeTypeSymbol); |
| 433 | | 513 | |
| ... | @@ -456,7 +536,7 @@ static bool eval_container_init_expr(EvalFn *ef, AstNode *node, ConstExprValue * | ... | @@ -456,7 +536,7 @@ static bool eval_container_init_expr(EvalFn *ef, AstNode *node, ConstExprValue * |
| 456 | ContainerInitKind kind = container_init_expr->kind; | 536 | ContainerInitKind kind = container_init_expr->kind; |
| 457 | | 537 | |
| 458 | if (container_init_expr->enum_type) { | 538 | if (container_init_expr->enum_type) { |
| 459 | zig_panic("TODO"); | 539 | zig_panic("TODO eval enum init"); |
| 460 | } | 540 | } |
| 461 | | 541 | |
| 462 | TypeTableEntry *container_type = resolve_expr_type(container_init_expr->type); | 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,7 +594,7 @@ static bool eval_container_init_expr(EvalFn *ef, AstNode *node, ConstExprValue * |
| 514 | elem_val->depends_on_compile_var; | 594 | elem_val->depends_on_compile_var; |
| 515 | } | 595 | } |
| 516 | } else { | 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,7 +954,7 @@ static bool eval_fn_call_builtin(EvalFn *ef, AstNode *node, ConstExprValue *out_ |
| 874 | case BuiltinFnIdEmbedFile: | 954 | case BuiltinFnIdEmbedFile: |
| 875 | case BuiltinFnIdCmpExchange: | 955 | case BuiltinFnIdCmpExchange: |
| 876 | case BuiltinFnIdTruncate: | 956 | case BuiltinFnIdTruncate: |
| 877 | zig_panic("TODO"); | 957 | zig_panic("TODO builtin function"); |
| 878 | case BuiltinFnIdBreakpoint: | 958 | case BuiltinFnIdBreakpoint: |
| 879 | case BuiltinFnIdInvalid: | 959 | case BuiltinFnIdInvalid: |
| 880 | case BuiltinFnIdFrameAddress: | 960 | case BuiltinFnIdFrameAddress: |
| ... | @@ -909,7 +989,7 @@ static bool eval_fn_call_expr(EvalFn *ef, AstNode *node, ConstExprValue *out_val | ... | @@ -909,7 +989,7 @@ static bool eval_fn_call_expr(EvalFn *ef, AstNode *node, ConstExprValue *out_val |
| 909 | if (fn_ref_expr->type == NodeTypeFieldAccessExpr && | 989 | if (fn_ref_expr->type == NodeTypeFieldAccessExpr && |
| 910 | fn_ref_expr->data.field_access_expr.is_member_fn) | 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 | if (!fn_table_entry) { | 995 | if (!fn_table_entry) { |
| ... | @@ -941,7 +1021,7 @@ static bool eval_field_access_expr(EvalFn *ef, AstNode *node, ConstExprValue *ou | ... | @@ -941,7 +1021,7 @@ static bool eval_field_access_expr(EvalFn *ef, AstNode *node, ConstExprValue *ou |
| 941 | if (struct_type->id == TypeTableEntryIdArray) { | 1021 | if (struct_type->id == TypeTableEntryIdArray) { |
| 942 | Buf *name = node->data.field_access_expr.field_name; | 1022 | Buf *name = node->data.field_access_expr.field_name; |
| 943 | assert(buf_eql_str(name, "len")); | 1023 | assert(buf_eql_str(name, "len")); |
| 944 | zig_panic("TODO"); | 1024 | zig_panic("TODO field access array"); |
| 945 | } else if (struct_type->id == TypeTableEntryIdStruct || (struct_type->id == TypeTableEntryIdPointer && | 1025 | } else if (struct_type->id == TypeTableEntryIdStruct || (struct_type->id == TypeTableEntryIdPointer && |
| 946 | struct_type->data.pointer.child_type->id == TypeTableEntryIdStruct)) | 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,17 +1034,17 @@ static bool eval_field_access_expr(EvalFn *ef, AstNode *node, ConstExprValue *ou |
| 954 | *out_val = *field_value; | 1034 | *out_val = *field_value; |
| 955 | assert(out_val->ok); | 1035 | assert(out_val->ok); |
| 956 | } else { | 1036 | } else { |
| 957 | zig_panic("TODO"); | 1037 | zig_panic("TODO field access struct"); |
| 958 | } | 1038 | } |
| 959 | } else if (struct_type->id == TypeTableEntryIdMetaType) { | 1039 | } else if (struct_type->id == TypeTableEntryIdMetaType) { |
| 960 | TypeTableEntry *child_type = resolve_expr_type(struct_expr); | 1040 | TypeTableEntry *child_type = resolve_expr_type(struct_expr); |
| 961 | if (child_type->id == TypeTableEntryIdPureError) { | 1041 | if (child_type->id == TypeTableEntryIdPureError) { |
| 962 | *out_val = get_resolved_expr(node)->const_val; | 1042 | *out_val = get_resolved_expr(node)->const_val; |
| 963 | } else { | 1043 | } else { |
| 964 | zig_panic("TODO"); | 1044 | zig_panic("TODO field access meta type"); |
| 965 | } | 1045 | } |
| 966 | } else if (struct_type->id == TypeTableEntryIdNamespace) { | 1046 | } else if (struct_type->id == TypeTableEntryIdNamespace) { |
| 967 | zig_panic("TODO"); | 1047 | zig_panic("TODO field access namespace"); |
| 968 | } else { | 1048 | } else { |
| 969 | zig_unreachable(); | 1049 | zig_unreachable(); |
| 970 | } | 1050 | } |
| ... | @@ -989,7 +1069,7 @@ static bool eval_for_expr(EvalFn *ef, AstNode *node, ConstExprValue *out_val) { | ... | @@ -989,7 +1069,7 @@ static bool eval_for_expr(EvalFn *ef, AstNode *node, ConstExprValue *out_val) { |
| 989 | Buf *elem_var_name = elem_node->data.symbol_expr.symbol; | 1069 | Buf *elem_var_name = elem_node->data.symbol_expr.symbol; |
| 990 | | 1070 | |
| 991 | if (node->data.for_expr.elem_is_ptr) { | 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 | Buf *index_var_name = nullptr; | 1075 | Buf *index_var_name = nullptr; |
| ... | @@ -1062,7 +1142,7 @@ static bool eval_array_access_expr(EvalFn *ef, AstNode *node, ConstExprValue *ou | ... | @@ -1062,7 +1142,7 @@ static bool eval_array_access_expr(EvalFn *ef, AstNode *node, ConstExprValue *ou |
| 1062 | | 1142 | |
| 1063 | if (array_type->id == TypeTableEntryIdPointer) { | 1143 | if (array_type->id == TypeTableEntryIdPointer) { |
| 1064 | if (index_int >= array_val.data.x_ptr.len) { | 1144 | if (index_int >= array_val.data.x_ptr.len) { |
| 1065 | zig_panic("TODO"); | 1145 | zig_panic("TODO array access pointer"); |
| 1066 | } | 1146 | } |
| 1067 | *out_val = *array_val.data.x_ptr.ptr[index_int]; | 1147 | *out_val = *array_val.data.x_ptr.ptr[index_int]; |
| 1068 | } else if (array_type->id == TypeTableEntryIdStruct) { | 1148 | } else if (array_type->id == TypeTableEntryIdStruct) { |
| ... | @@ -1071,7 +1151,7 @@ static bool eval_array_access_expr(EvalFn *ef, AstNode *node, ConstExprValue *ou | ... | @@ -1071,7 +1151,7 @@ static bool eval_array_access_expr(EvalFn *ef, AstNode *node, ConstExprValue *ou |
| 1071 | ConstExprValue *len_value = array_val.data.x_struct.fields[1]; | 1151 | ConstExprValue *len_value = array_val.data.x_struct.fields[1]; |
| 1072 | uint64_t len_int = len_value->data.x_bignum.data.x_uint; | 1152 | uint64_t len_int = len_value->data.x_bignum.data.x_uint; |
| 1073 | if (index_int >= len_int) { | 1153 | if (index_int >= len_int) { |
| 1074 | zig_panic("TODO"); | 1154 | zig_panic("TODO array access slice"); |
| 1075 | } | 1155 | } |
| 1076 | | 1156 | |
| 1077 | ConstExprValue *ptr_value = array_val.data.x_struct.fields[0]; | 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,7 +1159,7 @@ static bool eval_array_access_expr(EvalFn *ef, AstNode *node, ConstExprValue *ou |
| 1079 | } else if (array_type->id == TypeTableEntryIdArray) { | 1159 | } else if (array_type->id == TypeTableEntryIdArray) { |
| 1080 | uint64_t array_len = array_type->data.array.len; | 1160 | uint64_t array_len = array_type->data.array.len; |
| 1081 | if (index_int >= array_len) { | 1161 | if (index_int >= array_len) { |
| 1082 | zig_panic("TODO"); | 1162 | zig_panic("TODO array access array"); |
| 1083 | } | 1163 | } |
| 1084 | *out_val = *array_val.data.x_array.fields[index_int]; | 1164 | *out_val = *array_val.data.x_array.fields[index_int]; |
| 1085 | } else { | 1165 | } else { |
| ... | @@ -1152,7 +1232,7 @@ static bool eval_prefix_op_expr(EvalFn *ef, AstNode *node, ConstExprValue *out_v | ... | @@ -1152,7 +1232,7 @@ static bool eval_prefix_op_expr(EvalFn *ef, AstNode *node, ConstExprValue *out_v |
| 1152 | return true; | 1232 | return true; |
| 1153 | } | 1233 | } |
| 1154 | } else if (expr_type->id == TypeTableEntryIdFloat) { | 1234 | } else if (expr_type->id == TypeTableEntryIdFloat) { |
| 1155 | zig_panic("TODO"); | 1235 | zig_panic("TODO prefix op on floats"); |
| 1156 | } else { | 1236 | } else { |
| 1157 | zig_unreachable(); | 1237 | zig_unreachable(); |
| 1158 | } | 1238 | } |
| ... | @@ -1162,7 +1242,7 @@ static bool eval_prefix_op_expr(EvalFn *ef, AstNode *node, ConstExprValue *out_v | ... | @@ -1162,7 +1242,7 @@ static bool eval_prefix_op_expr(EvalFn *ef, AstNode *node, ConstExprValue *out_v |
| 1162 | case PrefixOpError: | 1242 | case PrefixOpError: |
| 1163 | case PrefixOpUnwrapError: | 1243 | case PrefixOpUnwrapError: |
| 1164 | case PrefixOpUnwrapMaybe: | 1244 | case PrefixOpUnwrapMaybe: |
| 1165 | zig_panic("TODO"); | 1245 | zig_panic("TODO more prefix operations"); |
| 1166 | case PrefixOpInvalid: | 1246 | case PrefixOpInvalid: |
| 1167 | zig_unreachable(); | 1247 | zig_unreachable(); |
| 1168 | } | 1248 | } |
| ... | @@ -1308,7 +1388,7 @@ static bool eval_expr(EvalFn *ef, AstNode *node, ConstExprValue *out) { | ... | @@ -1308,7 +1388,7 @@ static bool eval_expr(EvalFn *ef, AstNode *node, ConstExprValue *out) { |
| 1308 | case NodeTypeErrorType: | 1388 | case NodeTypeErrorType: |
| 1309 | case NodeTypeTypeLiteral: | 1389 | case NodeTypeTypeLiteral: |
| 1310 | case NodeTypeVarLiteral: | 1390 | case NodeTypeVarLiteral: |
| 1311 | zig_panic("TODO"); | 1391 | zig_panic("TODO expr node"); |
| 1312 | case NodeTypeRoot: | 1392 | case NodeTypeRoot: |
| 1313 | case NodeTypeFnProto: | 1393 | case NodeTypeFnProto: |
| 1314 | case NodeTypeFnDef: | 1394 | case NodeTypeFnDef: |