<commit_before># Copyright 2015, <NAME>
package F::List;

use warnings;
use strict;
use parent qw(F::NodeExpression);



sub desc {
    my $list = shift;
    return sprintf '%s [%d items]', $list->list_type, scalar $list->children;
}

sub list_type {
    my $list = shift;
    if ($list->is_collection && !$list->is_callidx) {
        return 'hash'               if $list->is_hash;
        return 'value list'         if $list->is_array;
    }
    return 'property index'         if $list->is_property;
    return 'named argument list'    if $list->is_call && $list->is_hash;
    return 'mixed argument list'    if $list->is_call && $list->is_mixed;
    return 'argument list'          if $list->is_call;
    return 'index list'             if $list->is_index;
    return 'object'                 if $list->is_hash;
    return 'set'                    if $list->children > 1;
    return 'single value'           if $list->children;
    return 'structural list';
}

# type      Example     is_array    is_hash     is_collection
# -----------------------------------------------------------
# Sets      ()          true        false       false
# Objects   (:)         false       true        false
# Hashes    [:]         false       true        true
# Lists     []          true        false       true
#
sub is_array      { shift->{array}      }
sub is_hash       { shift->{hash}       }
sub is_mixed      { shift->{mixed}      }
sub is_collection { shift->{collection} }
sub is_property   { shift->{property}   }

sub is_callidx { shift->{is_callidx} }
sub is_call    { $_[0]->is_callidx && !$_[0]->{is_index} }
sub is_index   { $_[0]->is_callidx &&  $_[0]->{is_index} }

sub new_item {
    my $list = shift;
    my $item = F::new('ListItem', 
        item_num => $list->{item_c}++
    );
    return $list->adopt($item);
}

sub perl_fmt {
    my $list = shift;
    my @children = $list->children;

    my $get_pairs = sub {
        join ', ', map {
            my $key = $_->first_child->key;
            my $val = $_->first_child->value->perl_fmt_do;
            "$key => $val"
        } @children;
    };

    my $get_items = sub {
        join ', ', map $_->perl_fmt_do, @children;
    };

    # it's either an array or a hash.
    if ($list->is_collection) {
        return hash => { pairs => $get_pairs->() } if $list->is_hash;
        return list => { items => $get_items->() } if $list->is_array;
    }

    # it's either a set or an object.

    # it has pairs but is not a collection, so it's an object.
    return object => { pairs => $get_pairs->() } if $list->is_hash;

    # it has more than one value. therefore it's a set.
    if (@children > 1) {
        my $first_child = shift @children;
        my $items_str   = join ', ', map $_->perl_fmt_do, @children;
        return set => {
            first_item  => $first_child->perl_fmt_do,
            other_items => $items_str
        };
    }
<commit_msg>quote keys in objects/hashes if they start with zero to preserve the preceding digits<commit_after># Copyright 2015, <NAME>
package F::List;

use warnings;
use strict;
use parent qw(F::NodeExpression);



sub desc {
    my $list = shift;
    return sprintf '%s [%d items]', $list->list_type, scalar $list->children;
}

sub list_type {
    my $list = shift;
    if ($list->is_collection && !$list->is_callidx) {
        return 'hash'               if $list->is_hash;
        return 'value list'         if $list->is_array;
    }
    return 'property index'         if $list->is_property;
    return 'named argument list'    if $list->is_call && $list->is_hash;
    return 'mixed argument list'    if $list->is_call && $list->is_mixed;
    return 'argument list'          if $list->is_call;
    return 'index list'             if $list->is_index;
    return 'object'                 if $list->is_hash;
    return 'set'                    if $list->children > 1;
    return 'single value'           if $list->children;
    return 'structural list';
}

# type      Example     is_array    is_hash     is_collection
# -----------------------------------------------------------
# Sets      ()          true        false       false
# Objects   (:)         false       true        false
# Hashes    [:]         false       true        true
# Lists     []          true        false       true
#
sub is_array      { shift->{array}      }
sub is_hash       { shift->{hash}       }
sub is_mixed      { shift->{mixed}      }
sub is_collection { shift->{collection} }
sub is_property   { shift->{property}   }

sub is_callidx { shift->{is_callidx} }
sub is_call    { $_[0]->is_callidx && !$_[0]->{is_index} }
sub is_index   { $_[0]->is_callidx &&  $_[0]->{is_index} }

sub new_item {
    my $list = shift;
    my $item = F::new('ListItem',
        item_num => $list->{item_c}++
    );
    return $list->adopt($item);
}

sub perl_fmt {
    my $list = shift;
    my @children = $list->children;

    my $get_pairs = sub {
        join ', ', map {
            my $key = $_->first_child->key;
               $key = "'$key'" if $key =~ m/^\d/;
            my $val = $_->first_child->value->perl_fmt_do;
            "$key => $val"
        } @children;
    };

    my $get_items = sub {
        join ', ', map $_->perl_fmt_do, @children;
    };

    # it's either an array or a hash.
    if ($list->is_collection) {
        return hash => { pairs => $get_pairs->() } if $list->is_hash;
        return list => { items => $get_items->() } if $list->is_array;
    }

    # it's either a set or an object.

    # it has pairs but is not a collection, so it's an object.
    return object => { pairs => $get_pairs->() } if $list->is_hash;

    # it has more than one value. therefore it's a set.
    if (@children > 1) {
        my $first_child = shift @children;
        my $items_str   = join ', ', map $_->perl_fmt_do, @children;
        return set => {
            first_item  => $first_child->perl_fmt_do,
            other_items => $items_str
        };
    }

{'fraction_non_alphanumeric': 0.15993294216261525, 'fraction_numerical': 0.003352891869237217, 'mean_word_length': 1.8613908872901679, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 119, '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': '6045617', 'n_tokens_mistral': 1948, 'n_tokens_neox': 1886, 'n_words': 522}