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