<commit_before>require "./TreeVisitor.cr"

module Charly::AST

  # Dump a human-readable version of the AST
  class DumpVisitor < TreeVisitor

    # Catch all rule
    visit ASTNode do
      io.puts name node
      rest children
    end

    visit StringLiteral do
      io << name node
      io << " | "
      io.puts "\"#{node.value}\""
    end

    visit PrecalculatedValue, NumericLiteral, BooleanLiteral do
      io << name node
      io << " | "
      io.puts node.value
    end

    visit IdentifierLiteral, FunctionLiteral, ClassLiteral, PrimitiveClassLiteral do
      io << name node
      io << " | "
      io.puts "\"#{node.name}\""
      rest children
    end

    visit UnaryExpression, BinaryExpression, ComparisonExpression do
      io << name node
      io << " | "
      io.puts node.operator
      rest children
    end

    macro rest(children)
      {{children}}.each_with_index do |child, index|

        unless child.is_a? ASTNode
          next
        end

        str = String.build do |str|
          child.accept self, str
        end

        str.lines.each_with_index do |line, line_index|

          if line_index == 0
            if {{children}}.size > 1 && index < {{children}}.size - 1
              io << "├─"
            else
              io << "└─"
            end
          else
            if {{children}}.size > 1 && index < {{children}}.size - 1
              io << "│ "
            else
              io << "  "
            end
          end

          io << " "
          io << line

          io << "\n"
        end
      end
    end

  end

end<commit_msg>Append newline after nodes with children<commit_after>require "./TreeVisitor.cr"

module Charly::AST

  # Dump a human-readable version of the AST
  class DumpVisitor < TreeVisitor

    # Catch all rule
    visit ASTNode do
      io.puts name node
      rest children
    end

    visit StringLiteral do
      io << name node
      io << " | "
      io.puts "\"#{node.value}\""
    end

    visit PrecalculatedValue, NumericLiteral, BooleanLiteral do
      io << name node
      io << " | "
      io.puts node.value
    end

    visit IdentifierLiteral, FunctionLiteral, ClassLiteral, PrimitiveClassLiteral do
      io << name node
      io << " | "
      io.puts "\"#{node.name}\""
      rest children
    end

    visit UnaryExpression, BinaryExpression, ComparisonExpression do
      io << name node
      io << " | "
      io.puts node.operator
      rest children
    end

    macro rest(children)
      {{children}}.each_with_index do |child, index|

        unless child.is_a? ASTNode
          next
        end

        str = String.build do |str|
          child.accept self, str
        end

        str.lines.each_with_index do |line, line_index|

          if line_index == 0
            if {{children}}.size > 1 && index < {{children}}.size - 1
              io << "├─"
            else
              io << "└─"
            end
          else
            if {{children}}.size > 1 && index < {{children}}.size - 1
              io << "│ "
            else
              io << "  "
            end
          end

          io << " "
          io << line

          io << "\n"
        end
      end

      io << "\n"
    end

  end

end
{'fraction_non_alphanumeric': 0.1019402525408069, 'fraction_numerical': 0.003079765937788728, 'mean_word_length': 1.4624715693707353, 'pattern_counts': {'":': 0, '<': 71, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '650954', 'n_tokens_mistral': 973, 'n_tokens_neox': 919, 'n_words': 282}