<commit_before># Copyright (C) 2004-2008, Parrot Foundation.

# $Id$

=head1 NAME

Parrot::Pmc2c - PMC to C Code Generation

=head1 SYNOPSIS

    use Parrot::Pmc2c;

=head1 DESCRIPTION

C<Parrot::Pmc2c> is used by F<tools/build/pmc2c.pl> to generate C code from PMC files.

=head2 Functions

=over

=cut

package Parrot::Pmc2c::PMC::RO;
use strict;
use warnings;
use base qw( Parrot::Pmc2c::PMC );

use Parrot::Pmc2c::Emitter ();
use Parrot::Pmc2c::PMCEmitter ();
use Parrot::Pmc2c::Method ();
use Parrot::Pmc2c::UtilFunctions qw( return_statement );
use Text::Balanced 'extract_bracketed';

=item C<make_RO($type)>

Create a RO version of the PMC

=cut

sub new {
    my ( $class, $parent ) = @_;
    my $classname = ref($parent) || $class;

    my $self = bless Parrot::Pmc2c::PMC->new(
        {
            parents => [ $parent->name, @{ $parent->parents } ],    # prepend self to parrent
            flags => { ( %{ $parent->get_flags } ), 'is_ro' => 1 }, # copy flags, set is_const
            name       => $parent->name . "_ro",                    # set pmcname
            vtable     => $parent->vtable,                          # and alias vtable
            parentname => $parent->name,                            # set parentname
        }
    ), $classname;

    $parent->set_flag('has_ro');

    {

      # autogenerate for nonstandard types
      # (RT#44433 is this appropriate or do we want them to each be explicitly cleared to have RO ?)
        no strict 'refs';
        if ( !@{ ref($self) . '::ISA' } ) {
            @{ ref($self) . '::ISA' } = "Parrot::Pmc2c::PMC::RO";
        }
    }

    foreach my $vt_method ( @{ $self->vtable->methods } ) {
        my $vt_method_name = $vt_method->name;
        if ( $vt_method_name eq 'find_method' ) {
            my $ro_method = Parrot::Pmc2c::Method->new(
                {
                    name        => $vt_method_name,
                    parent_name => $parent->name,
                    return_type => $vt_method->return_type,
                    parameters  => $vt_method->parameters,
                    type        => Parrot::Pmc2c::Method::VTABLE,
                }
            );
            my $find_method_parent;
            if ( $parent->implements_vtable($vt_method_name) ) {
                $find_method_parent = $parent->name;
            }
            else {
                $find_method_parent = $parent->{super}{$vt_method_name};
            }
            my $real_findmethod = 'interp->vtables[enum_class_' . $find_method_parent . ']->find_method';
            my $body            = <<"EOC";
    PMC *const method = $real_findmethod(interp, pmc, method_name);
    if (!PMC_IS_NULL(VTABLE_getprop(interp, method, CONST_STRING_GEN(interp, "write"))))
        return PMCNULL;<commit_msg>Use pmc_type(Foo) instead of direct enum_class_Foo construction in RO.find_method handling.<commit_after># Copyright (C) 2004-2008, Parrot Foundation.

# $Id$

=head1 NAME

Parrot::Pmc2c - PMC to C Code Generation

=head1 SYNOPSIS

    use Parrot::Pmc2c;

=head1 DESCRIPTION

C<Parrot::Pmc2c> is used by F<tools/build/pmc2c.pl> to generate C code from PMC files.

=head2 Functions

=over

=cut

package Parrot::Pmc2c::PMC::RO;
use strict;
use warnings;
use base qw( Parrot::Pmc2c::PMC );

use Parrot::Pmc2c::Emitter ();
use Parrot::Pmc2c::PMCEmitter ();
use Parrot::Pmc2c::Method ();
use Parrot::Pmc2c::UtilFunctions qw( return_statement );
use Text::Balanced 'extract_bracketed';

=item C<make_RO($type)>

Create a RO version of the PMC

=cut

sub new {
    my ( $class, $parent ) = @_;
    my $classname = ref($parent) || $class;

    my $self = bless Parrot::Pmc2c::PMC->new(
        {
            parents => [ $parent->name, @{ $parent->parents } ],    # prepend self to parrent
            flags => { ( %{ $parent->get_flags } ), 'is_ro' => 1 }, # copy flags, set is_const
            name       => $parent->name . "_ro",                    # set pmcname
            vtable     => $parent->vtable,                          # and alias vtable
            parentname => $parent->name,                            # set parentname
        }
    ), $classname;

    $parent->set_flag('has_ro');

    {

      # autogenerate for nonstandard types
      # (RT#44433 is this appropriate or do we want them to each be explicitly cleared to have RO ?)
        no strict 'refs';
        if ( !@{ ref($self) . '::ISA' } ) {
            @{ ref($self) . '::ISA' } = "Parrot::Pmc2c::PMC::RO";
        }
    }

    foreach my $vt_method ( @{ $self->vtable->methods } ) {
        my $vt_method_name = $vt_method->name;
        if ( $vt_method_name eq 'find_method' ) {
            my $ro_method = Parrot::Pmc2c::Method->new(
                {
                    name        => $vt_method_name,
                    parent_name => $parent->name,
                    return_type => $vt_method->return_type,
                    parameters  => $vt_method->parameters,
                    type        => Parrot::Pmc2c::Method::VTABLE,
                }
            );
            my $find_method_parent;
            if ( $parent->implements_vtable($vt_method_name) ) {
                $find_method_parent = $parent->name;
            }
            else {
                $find_method_parent = $parent->{super}{$vt_method_name};
            }
            # We can't use enum_class_Foo there. $parent can be non-core PMC.
            my $real_findmethod = 'interp->vtables[pmc_type(interp, Parrot_str_new_constant(interp, "' . $find_method_parent . '"))]->find_method';
            my $body            = <<"EOC";
    PMC *const method = $real_findmethod(interp, pmc, method_name);
    if (!PMC_IS_NULL(VTABLE_getprop(interp, method, CONST_STRING_GEN(interp, "write"))))
        return PMCNULL;
{'fraction_non_alphanumeric': 0.13669565217391305, 'fraction_numerical': 0.011130434782608696, 'mean_word_length': 2.0886143931256713, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 71, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '486607', 'n_tokens_mistral': 1939, 'n_tokens_neox': 1857, 'n_words': 415}