| ... | @@ -342,13 +342,23 @@ static void print_symbol(AstRender *ar, Buf *symbol) { | ... | @@ -342,13 +342,23 @@ static void print_symbol(AstRender *ar, Buf *symbol) { |
| 342 | fprintf(ar->f, "@\"%s\"", buf_ptr(&escaped)); | 342 | fprintf(ar->f, "@\"%s\"", buf_ptr(&escaped)); |
| 343 | } | 343 | } |
| 344 | | 344 | |
| 345 | static void render_node(AstRender *ar, AstNode *node) { | 345 | static void render_node_extra(AstRender *ar, AstNode *node, bool grouped); |
| | 346 | |
| | 347 | static void render_node_grouped(AstRender *ar, AstNode *node) { |
| | 348 | return render_node_extra(ar, node, true); |
| | 349 | } |
| | 350 | |
| | 351 | static void render_node_ungrouped(AstRender *ar, AstNode *node) { |
| | 352 | return render_node_extra(ar, node, false); |
| | 353 | } |
| | 354 | |
| | 355 | static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) { |
| 346 | switch (node->type) { | 356 | switch (node->type) { |
| 347 | case NodeTypeRoot: | 357 | case NodeTypeRoot: |
| 348 | for (size_t i = 0; i < node->data.root.top_level_decls.length; i += 1) { | 358 | for (size_t i = 0; i < node->data.root.top_level_decls.length; i += 1) { |
| 349 | AstNode *child = node->data.root.top_level_decls.at(i); | 359 | AstNode *child = node->data.root.top_level_decls.at(i); |
| 350 | print_indent(ar); | 360 | print_indent(ar); |
| 351 | render_node(ar, child); | 361 | render_node_grouped(ar, child); |
| 352 | | 362 | |
| 353 | if (child->type == NodeTypeUse || | 363 | if (child->type == NodeTypeUse || |
| 354 | child->type == NodeTypeVariableDeclaration || | 364 | child->type == NodeTypeVariableDeclaration || |
| ... | @@ -381,7 +391,7 @@ static void render_node(AstRender *ar, AstNode *node) { | ... | @@ -381,7 +391,7 @@ static void render_node(AstRender *ar, AstNode *node) { |
| 381 | print_symbol(ar, param_decl->data.param_decl.name); | 391 | print_symbol(ar, param_decl->data.param_decl.name); |
| 382 | fprintf(ar->f, ": "); | 392 | fprintf(ar->f, ": "); |
| 383 | } | 393 | } |
| 384 | render_node(ar, param_decl->data.param_decl.type); | 394 | render_node_grouped(ar, param_decl->data.param_decl.type); |
| 385 | | 395 | |
| 386 | if (arg_i + 1 < arg_count || is_var_args) { | 396 | if (arg_i + 1 < arg_count || is_var_args) { |
| 387 | fprintf(ar->f, ", "); | 397 | fprintf(ar->f, ", "); |
| ... | @@ -394,14 +404,14 @@ static void render_node(AstRender *ar, AstNode *node) { | ... | @@ -394,14 +404,14 @@ static void render_node(AstRender *ar, AstNode *node) { |
| 394 | | 404 | |
| 395 | AstNode *return_type_node = node->data.fn_proto.return_type; | 405 | AstNode *return_type_node = node->data.fn_proto.return_type; |
| 396 | fprintf(ar->f, " -> "); | 406 | fprintf(ar->f, " -> "); |
| 397 | render_node(ar, return_type_node); | 407 | render_node_grouped(ar, return_type_node); |
| 398 | break; | 408 | break; |
| 399 | } | 409 | } |
| 400 | case NodeTypeFnDef: | 410 | case NodeTypeFnDef: |
| 401 | { | 411 | { |
| 402 | render_node(ar, node->data.fn_def.fn_proto); | 412 | render_node_grouped(ar, node->data.fn_def.fn_proto); |
| 403 | fprintf(ar->f, " "); | 413 | fprintf(ar->f, " "); |
| 404 | render_node(ar, node->data.fn_def.body); | 414 | render_node_grouped(ar, node->data.fn_def.body); |
| 405 | break; | 415 | break; |
| 406 | } | 416 | } |
| 407 | case NodeTypeBlock: | 417 | case NodeTypeBlock: |
| ... | @@ -414,7 +424,7 @@ static void render_node(AstRender *ar, AstNode *node) { | ... | @@ -414,7 +424,7 @@ static void render_node(AstRender *ar, AstNode *node) { |
| 414 | for (size_t i = 0; i < node->data.block.statements.length; i += 1) { | 424 | for (size_t i = 0; i < node->data.block.statements.length; i += 1) { |
| 415 | AstNode *statement = node->data.block.statements.at(i); | 425 | AstNode *statement = node->data.block.statements.at(i); |
| 416 | print_indent(ar); | 426 | print_indent(ar); |
| 417 | render_node(ar, statement); | 427 | render_node_grouped(ar, statement); |
| 418 | if (i != node->data.block.statements.length - 1) | 428 | if (i != node->data.block.statements.length - 1) |
| 419 | fprintf(ar->f, ";"); | 429 | fprintf(ar->f, ";"); |
| 420 | fprintf(ar->f, "\n"); | 430 | fprintf(ar->f, "\n"); |
| ... | @@ -427,14 +437,14 @@ static void render_node(AstRender *ar, AstNode *node) { | ... | @@ -427,14 +437,14 @@ static void render_node(AstRender *ar, AstNode *node) { |
| 427 | { | 437 | { |
| 428 | const char *return_str = return_string(node->data.return_expr.kind); | 438 | const char *return_str = return_string(node->data.return_expr.kind); |
| 429 | fprintf(ar->f, "%s ", return_str); | 439 | fprintf(ar->f, "%s ", return_str); |
| 430 | render_node(ar, node->data.return_expr.expr); | 440 | render_node_grouped(ar, node->data.return_expr.expr); |
| 431 | break; | 441 | break; |
| 432 | } | 442 | } |
| 433 | case NodeTypeDefer: | 443 | case NodeTypeDefer: |
| 434 | { | 444 | { |
| 435 | const char *defer_str = defer_string(node->data.defer.kind); | 445 | const char *defer_str = defer_string(node->data.defer.kind); |
| 436 | fprintf(ar->f, "%s ", defer_str); | 446 | fprintf(ar->f, "%s ", defer_str); |
| 437 | render_node(ar, node->data.return_expr.expr); | 447 | render_node_grouped(ar, node->data.return_expr.expr); |
| 438 | break; | 448 | break; |
| 439 | } | 449 | } |
| 440 | case NodeTypeVariableDeclaration: | 450 | case NodeTypeVariableDeclaration: |
| ... | @@ -447,11 +457,11 @@ static void render_node(AstRender *ar, AstNode *node) { | ... | @@ -447,11 +457,11 @@ static void render_node(AstRender *ar, AstNode *node) { |
| 447 | | 457 | |
| 448 | if (node->data.variable_declaration.type) { | 458 | if (node->data.variable_declaration.type) { |
| 449 | fprintf(ar->f, ": "); | 459 | fprintf(ar->f, ": "); |
| 450 | render_node(ar, node->data.variable_declaration.type); | 460 | render_node_grouped(ar, node->data.variable_declaration.type); |
| 451 | } | 461 | } |
| 452 | if (node->data.variable_declaration.expr) { | 462 | if (node->data.variable_declaration.expr) { |
| 453 | fprintf(ar->f, " = "); | 463 | fprintf(ar->f, " = "); |
| 454 | render_node(ar, node->data.variable_declaration.expr); | 464 | render_node_grouped(ar, node->data.variable_declaration.expr); |
| 455 | } | 465 | } |
| 456 | break; | 466 | break; |
| 457 | } | 467 | } |
| ... | @@ -460,15 +470,15 @@ static void render_node(AstRender *ar, AstNode *node) { | ... | @@ -460,15 +470,15 @@ static void render_node(AstRender *ar, AstNode *node) { |
| 460 | const char *pub_str = visib_mod_string(node->data.type_decl.top_level_decl.visib_mod); | 470 | const char *pub_str = visib_mod_string(node->data.type_decl.top_level_decl.visib_mod); |
| 461 | const char *var_name = buf_ptr(node->data.type_decl.symbol); | 471 | const char *var_name = buf_ptr(node->data.type_decl.symbol); |
| 462 | fprintf(ar->f, "%stype %s = ", pub_str, var_name); | 472 | fprintf(ar->f, "%stype %s = ", pub_str, var_name); |
| 463 | render_node(ar, node->data.type_decl.child_type); | 473 | render_node_grouped(ar, node->data.type_decl.child_type); |
| 464 | break; | 474 | break; |
| 465 | } | 475 | } |
| 466 | case NodeTypeBinOpExpr: | 476 | case NodeTypeBinOpExpr: |
| 467 | fprintf(ar->f, "("); | 477 | if (!grouped) fprintf(ar->f, "("); |
| 468 | render_node(ar, node->data.bin_op_expr.op1); | 478 | render_node_ungrouped(ar, node->data.bin_op_expr.op1); |
| 469 | fprintf(ar->f, " %s ", bin_op_str(node->data.bin_op_expr.bin_op)); | 479 | fprintf(ar->f, " %s ", bin_op_str(node->data.bin_op_expr.bin_op)); |
| 470 | render_node(ar, node->data.bin_op_expr.op2); | 480 | render_node_ungrouped(ar, node->data.bin_op_expr.op2); |
| 471 | fprintf(ar->f, ")"); | 481 | if (!grouped) fprintf(ar->f, ")"); |
| 472 | break; | 482 | break; |
| 473 | case NodeTypeNumberLiteral: | 483 | case NodeTypeNumberLiteral: |
| 474 | switch (node->data.number_literal.bignum->kind) { | 484 | switch (node->data.number_literal.bignum->kind) { |
| ... | @@ -511,7 +521,7 @@ static void render_node(AstRender *ar, AstNode *node) { | ... | @@ -511,7 +521,7 @@ static void render_node(AstRender *ar, AstNode *node) { |
| 511 | PrefixOp op = node->data.prefix_op_expr.prefix_op; | 521 | PrefixOp op = node->data.prefix_op_expr.prefix_op; |
| 512 | fprintf(ar->f, "%s", prefix_op_str(op)); | 522 | fprintf(ar->f, "%s", prefix_op_str(op)); |
| 513 | | 523 | |
| 514 | render_node(ar, node->data.prefix_op_expr.primary_expr); | 524 | render_node_ungrouped(ar, node->data.prefix_op_expr.primary_expr); |
| 515 | break; | 525 | break; |
| 516 | } | 526 | } |
| 517 | case NodeTypeFnCallExpr: | 527 | case NodeTypeFnCallExpr: |
| ... | @@ -520,7 +530,7 @@ static void render_node(AstRender *ar, AstNode *node) { | ... | @@ -520,7 +530,7 @@ static void render_node(AstRender *ar, AstNode *node) { |
| 520 | } else { | 530 | } else { |
| 521 | fprintf(ar->f, "("); | 531 | fprintf(ar->f, "("); |
| 522 | } | 532 | } |
| 523 | render_node(ar, node->data.fn_call_expr.fn_ref_expr); | 533 | render_node_ungrouped(ar, node->data.fn_call_expr.fn_ref_expr); |
| 524 | if (!node->data.fn_call_expr.is_builtin) { | 534 | if (!node->data.fn_call_expr.is_builtin) { |
| 525 | fprintf(ar->f, ")"); | 535 | fprintf(ar->f, ")"); |
| 526 | } | 536 | } |
| ... | @@ -530,21 +540,21 @@ static void render_node(AstRender *ar, AstNode *node) { | ... | @@ -530,21 +540,21 @@ static void render_node(AstRender *ar, AstNode *node) { |
| 530 | if (i != 0) { | 540 | if (i != 0) { |
| 531 | fprintf(ar->f, ", "); | 541 | fprintf(ar->f, ", "); |
| 532 | } | 542 | } |
| 533 | render_node(ar, param); | 543 | render_node_grouped(ar, param); |
| 534 | } | 544 | } |
| 535 | fprintf(ar->f, ")"); | 545 | fprintf(ar->f, ")"); |
| 536 | break; | 546 | break; |
| 537 | case NodeTypeArrayAccessExpr: | 547 | case NodeTypeArrayAccessExpr: |
| 538 | render_node(ar, node->data.array_access_expr.array_ref_expr); | 548 | render_node_ungrouped(ar, node->data.array_access_expr.array_ref_expr); |
| 539 | fprintf(ar->f, "["); | 549 | fprintf(ar->f, "["); |
| 540 | render_node(ar, node->data.array_access_expr.subscript); | 550 | render_node_grouped(ar, node->data.array_access_expr.subscript); |
| 541 | fprintf(ar->f, "]"); | 551 | fprintf(ar->f, "]"); |
| 542 | break; | 552 | break; |
| 543 | case NodeTypeFieldAccessExpr: | 553 | case NodeTypeFieldAccessExpr: |
| 544 | { | 554 | { |
| 545 | AstNode *lhs = node->data.field_access_expr.struct_expr; | 555 | AstNode *lhs = node->data.field_access_expr.struct_expr; |
| 546 | Buf *rhs = node->data.field_access_expr.field_name; | 556 | Buf *rhs = node->data.field_access_expr.field_name; |
| 547 | render_node(ar, lhs); | 557 | render_node_ungrouped(ar, lhs); |
| 548 | fprintf(ar->f, "."); | 558 | fprintf(ar->f, "."); |
| 549 | print_symbol(ar, rhs); | 559 | print_symbol(ar, rhs); |
| 550 | break; | 560 | break; |
| ... | @@ -565,7 +575,7 @@ static void render_node(AstRender *ar, AstNode *node) { | ... | @@ -565,7 +575,7 @@ static void render_node(AstRender *ar, AstNode *node) { |
| 565 | print_indent(ar); | 575 | print_indent(ar); |
| 566 | print_symbol(ar, field_node->data.struct_field.name); | 576 | print_symbol(ar, field_node->data.struct_field.name); |
| 567 | fprintf(ar->f, ": "); | 577 | fprintf(ar->f, ": "); |
| 568 | render_node(ar, field_node->data.struct_field.type); | 578 | render_node_grouped(ar, field_node->data.struct_field.type); |
| 569 | fprintf(ar->f, ",\n"); | 579 | fprintf(ar->f, ",\n"); |
| 570 | } | 580 | } |
| 571 | | 581 | |
| ... | @@ -574,9 +584,8 @@ static void render_node(AstRender *ar, AstNode *node) { | ... | @@ -574,9 +584,8 @@ static void render_node(AstRender *ar, AstNode *node) { |
| 574 | break; | 584 | break; |
| 575 | } | 585 | } |
| 576 | case NodeTypeContainerInitExpr: | 586 | case NodeTypeContainerInitExpr: |
| 577 | fprintf(ar->f, "("); | 587 | render_node_ungrouped(ar, node->data.container_init_expr.type); |
| 578 | render_node(ar, node->data.container_init_expr.type); | 588 | fprintf(ar->f, "{"); |
| 579 | fprintf(ar->f, "){"); | | |
| 580 | assert(node->data.container_init_expr.entries.length == 0); | 589 | assert(node->data.container_init_expr.entries.length == 0); |
| 581 | fprintf(ar->f, "}"); | 590 | fprintf(ar->f, "}"); |
| 582 | break; | 591 | break; |
| ... | @@ -584,13 +593,13 @@ static void render_node(AstRender *ar, AstNode *node) { | ... | @@ -584,13 +593,13 @@ static void render_node(AstRender *ar, AstNode *node) { |
| 584 | { | 593 | { |
| 585 | fprintf(ar->f, "["); | 594 | fprintf(ar->f, "["); |
| 586 | if (node->data.array_type.size) { | 595 | if (node->data.array_type.size) { |
| 587 | render_node(ar, node->data.array_type.size); | 596 | render_node_grouped(ar, node->data.array_type.size); |
| 588 | } | 597 | } |
| 589 | fprintf(ar->f, "]"); | 598 | fprintf(ar->f, "]"); |
| 590 | if (node->data.array_type.is_const) { | 599 | if (node->data.array_type.is_const) { |
| 591 | fprintf(ar->f, "const "); | 600 | fprintf(ar->f, "const "); |
| 592 | } | 601 | } |
| 593 | render_node(ar, node->data.array_type.child_type); | 602 | render_node_ungrouped(ar, node->data.array_type.child_type); |
| 594 | break; | 603 | break; |
| 595 | } | 604 | } |
| 596 | case NodeTypeErrorType: | 605 | case NodeTypeErrorType: |
| ... | @@ -622,7 +631,7 @@ static void render_node(AstRender *ar, AstNode *node) { | ... | @@ -622,7 +631,7 @@ static void render_node(AstRender *ar, AstNode *node) { |
| 622 | buf_ptr(asm_output->constraint)); | 631 | buf_ptr(asm_output->constraint)); |
| 623 | if (asm_output->return_type) { | 632 | if (asm_output->return_type) { |
| 624 | fprintf(ar->f, "-> "); | 633 | fprintf(ar->f, "-> "); |
| 625 | render_node(ar, asm_output->return_type); | 634 | render_node_grouped(ar, asm_output->return_type); |
| 626 | } else { | 635 | } else { |
| 627 | fprintf(ar->f, "%s", buf_ptr(asm_output->variable_name)); | 636 | fprintf(ar->f, "%s", buf_ptr(asm_output->variable_name)); |
| 628 | } | 637 | } |
| ... | @@ -642,7 +651,7 @@ static void render_node(AstRender *ar, AstNode *node) { | ... | @@ -642,7 +651,7 @@ static void render_node(AstRender *ar, AstNode *node) { |
| 642 | fprintf(ar->f, "[%s] \"%s\" (", | 651 | fprintf(ar->f, "[%s] \"%s\" (", |
| 643 | buf_ptr(asm_input->asm_symbolic_name), | 652 | buf_ptr(asm_input->asm_symbolic_name), |
| 644 | buf_ptr(asm_input->constraint)); | 653 | buf_ptr(asm_input->constraint)); |
| 645 | render_node(ar, asm_input->expr); | 654 | render_node_grouped(ar, asm_input->expr); |
| 646 | fprintf(ar->f, ")"); | 655 | fprintf(ar->f, ")"); |
| 647 | } | 656 | } |
| 648 | fprintf(ar->f, "\n"); | 657 | fprintf(ar->f, "\n"); |
| ... | @@ -660,13 +669,13 @@ static void render_node(AstRender *ar, AstNode *node) { | ... | @@ -660,13 +669,13 @@ static void render_node(AstRender *ar, AstNode *node) { |
| 660 | { | 669 | { |
| 661 | const char *inline_str = node->data.while_expr.is_inline ? "inline " : ""; | 670 | const char *inline_str = node->data.while_expr.is_inline ? "inline " : ""; |
| 662 | fprintf(ar->f, "%swhile (", inline_str); | 671 | fprintf(ar->f, "%swhile (", inline_str); |
| 663 | render_node(ar, node->data.while_expr.condition); | 672 | render_node_grouped(ar, node->data.while_expr.condition); |
| 664 | if (node->data.while_expr.continue_expr) { | 673 | if (node->data.while_expr.continue_expr) { |
| 665 | fprintf(ar->f, "; "); | 674 | fprintf(ar->f, "; "); |
| 666 | render_node(ar, node->data.while_expr.continue_expr); | 675 | render_node_grouped(ar, node->data.while_expr.continue_expr); |
| 667 | } | 676 | } |
| 668 | fprintf(ar->f, ") "); | 677 | fprintf(ar->f, ") "); |
| 669 | render_node(ar, node->data.while_expr.body); | 678 | render_node_grouped(ar, node->data.while_expr.body); |
| 670 | break; | 679 | break; |
| 671 | } | 680 | } |
| 672 | case NodeTypeThisLiteral: | 681 | case NodeTypeThisLiteral: |
| ... | @@ -680,6 +689,18 @@ static void render_node(AstRender *ar, AstNode *node) { | ... | @@ -680,6 +689,18 @@ static void render_node(AstRender *ar, AstNode *node) { |
| 680 | fprintf(ar->f, "%s", bool_str); | 689 | fprintf(ar->f, "%s", bool_str); |
| 681 | break; | 690 | break; |
| 682 | } | 691 | } |
| | 692 | case NodeTypeIfBoolExpr: |
| | 693 | { |
| | 694 | fprintf(ar->f, "if ("); |
| | 695 | render_node_grouped(ar, node->data.if_bool_expr.condition); |
| | 696 | fprintf(ar->f, ") "); |
| | 697 | render_node_grouped(ar, node->data.if_bool_expr.then_block); |
| | 698 | if (node->data.if_bool_expr.else_node) { |
| | 699 | fprintf(ar->f, "else "); |
| | 700 | render_node_grouped(ar, node->data.if_bool_expr.else_node); |
| | 701 | } |
| | 702 | break; |
| | 703 | } |
| 683 | case NodeTypeFnDecl: | 704 | case NodeTypeFnDecl: |
| 684 | case NodeTypeParamDecl: | 705 | case NodeTypeParamDecl: |
| 685 | case NodeTypeErrorValueDecl: | 706 | case NodeTypeErrorValueDecl: |
| ... | @@ -690,7 +711,6 @@ static void render_node(AstRender *ar, AstNode *node) { | ... | @@ -690,7 +711,6 @@ static void render_node(AstRender *ar, AstNode *node) { |
| 690 | case NodeTypeUse: | 711 | case NodeTypeUse: |
| 691 | case NodeTypeNullLiteral: | 712 | case NodeTypeNullLiteral: |
| 692 | case NodeTypeZeroesLiteral: | 713 | case NodeTypeZeroesLiteral: |
| 693 | case NodeTypeIfBoolExpr: | | |
| 694 | case NodeTypeIfVarExpr: | 714 | case NodeTypeIfVarExpr: |
| 695 | case NodeTypeForExpr: | 715 | case NodeTypeForExpr: |
| 696 | case NodeTypeSwitchExpr: | 716 | case NodeTypeSwitchExpr: |
| ... | @@ -711,5 +731,5 @@ void ast_render(FILE *f, AstNode *node, int indent_size) { | ... | @@ -711,5 +731,5 @@ void ast_render(FILE *f, AstNode *node, int indent_size) { |
| 711 | ar.indent_size = indent_size; | 731 | ar.indent_size = indent_size; |
| 712 | ar.indent = 0; | 732 | ar.indent = 0; |
| 713 | | 733 | |
| 714 | render_node(&ar, node); | 734 | render_node_grouped(&ar, node); |
| 715 | } | 735 | } |