# Do not edit this file - Generated by Perlito5 9.025

{
    package main;
    package Perlito5::Grammar::Bareword;
    use strict ;
    sub Perlito5::Grammar::Bareword::the_object {
        my $str = $_[0];
        my $pos = $_[1];
        my $MATCH = {"str" => $str, "from" => $pos, "to" => $pos, };
        my $tmp = ((do {
            my $tmp100 = $MATCH->{"to"};
            (((do {
                my $tmp = $MATCH;
                $MATCH = {"from" => $tmp->{"to"}, "to" => $tmp->{"to"}, };
                my $res = (("\$" eq $str->[($MATCH->{"to"}) + 0]) && ($MATCH->{"to"} += 1));
                $MATCH = $tmp;
                $res ? 1 : 0
            }) && (do {
                my $m2 = Perlito5::Grammar::Sigil::term_sigil($str, $MATCH->{"to"});
                if ($m2) {
                    $MATCH->{"to"} = $m2->{"to"};
                    $MATCH->{"Perlito5::Grammar::Sigil::term_sigil"} = $m2;
                    1
                }
                else {;
                    0
                }
            }) && (do {
                $MATCH->{"capture"} = Perlito5::Match::flat($MATCH->{"Perlito5::Grammar::Sigil::term_sigil"})->[1];
                1
            }))) || ($MATCH->{"to"} = $tmp100, ((("{" eq $str->[($MATCH->{"to"}) + 0]) && ($MATCH->{"to"} += 1)) && (do {
                my $m2 = Perlito5::Grammar::Expression::curly_parse($str, $MATCH->{"to"});
                if ($m2) {
                    $MATCH->{"to"} = $m2->{"to"};
                    $MATCH->{"Perlito5::Grammar::Expression::curly_parse"} = $m2;
                    1
                }
                else {;
                    0
                }
            }) && (("}" eq $str->[($MATCH->{"to"}) + 0]) && ($MATCH->{"to"} += 1)) && (do {
                $MATCH->{"capture"} = Perlito5::Match::flat($MATCH->{"Perlito5::Grammar::Expression::curly_parse"});
                1
            }))) || ($MATCH->{"to"} = $tmp100, ((do {
                my $m2 = Perlito5::Grammar::Print::typeglob($str, $MATCH->{"to"});
                if ($m2) {
                    $MATCH->{"to"} = $m2->{"to"};
                    $MATCH->{"Perlito5::Grammar::Print::typeglob"} = $m2;
                    1
                }
                else {;
                    0
                }
            }) && (do {
                $MATCH->{"capture"} = Perlito5::Match::flat($MATCH->{"Perlito5::Grammar::Print::typeglob"});
                1
            })))
        }));
        $tmp ? $MATCH : undef
    }
    sub Perlito5::Grammar::Bareword::term_bareword {
        my $str = $_[0];
        my $pos = $_[1];
        my $p = $pos;
        my $m_namespace = Perlito5::Grammar::optional_namespace_before_ident($str, $p);
        my $namespace = Perlito5::Match::flat($m_namespace);
        $p = $m_namespace->{"to"};
        my $m_name = Perlito5::Grammar::ident($str, $p);
        if (!$m_name) {
            if ($namespace) {
                $m_namespace->{"capture"} = ["term", Perlito5::AST::Var::->new("sigil", "::", "name", '', "namespace", $namespace)];
                return $m_namespace
            }
            return
        }
        my $name = Perlito5::Match::flat($m_name);
        $p = $m_name->{"to"};
        if ($str->[$p] eq ":" && $str->[$p + 1] eq ":") {
            $m_name->{"to"} = $p + 2;
            $m_name->{"capture"} = ["term", Perlito5::AST::Var::->new("sigil", "::", "name", '', "namespace", $namespace . "::" . $name)];
            return $m_name
        }
        my $full_name = $name;
        $namespace && ($full_name = $namespace . "::" . $name);
        my $m = Perlito5::Grammar::Space::ws($str, $p);
        if ($m) {;
            $p = $m->{"to"}
        }
        my $invocant;
        my $is_subroutine_name;
        my $effective_name = ($namespace || $Perlito5::PKG_NAME) . "::" . $name;
        if (exists(&{$effective_name})) {
            my $p = eval {;
                prototype($effective_name)
            };
            $Perlito5::PROTO->{$effective_name} = $p
        }
        if (exists($Perlito5::Grammar::Print::Print{$name})) {;
            $invocant = undef
        }
        elsif (exists($Perlito5::PROTO->{$effective_name}) || ((!$namespace || $namespace eq "CORE") && exists($Perlito5::CORE_PROTO->{"CORE::" . $name}))) {
            if ($name eq "__END__" || $name eq "__DATA__") {;
                return Perlito5::Grammar::Space::term_end(@_)
            }
            $is_subroutine_name = 1;
            $invocant = Perlito5::Grammar::full_ident($str, $p);
            if ($invocant) {
                my $package = Perlito5::Match::flat($invocant);
                if ($package) {
                    $invocant->{"capture"} = Perlito5::AST::Var::->new("sigil", "::", "name", '', "namespace", $package);
                    if ($str->[$invocant->{"to"}] eq ":" && $str->[($invocant->{"to"}) + 1] eq ":") {;
                        $invocant->{"to"} = ($invocant->{"to"}) + 2
                    }
                    elsif (!$Perlito5::PACKAGES->{$package}) {;
                        $invocant = undef
                    }
                }
            }
        }
        else {;
            $invocant = Perlito5::Grammar::Bareword::the_object($str, $p)
        }
        if ($invocant) {
            $p = $invocant->{"to"};
            my $arg = [];
            $m = Perlito5::Grammar::Space::ws($str, $p);
            $m && ($p = $m->{"to"});
            if ($str->[$p] eq "-" && $str->[$p + 1] eq ">") {}
            elsif ($str->[$p] eq "(") {
                my $m = Perlito5::Grammar::Expression::term_paren($str, $p);
                if ($m) {
                    $arg = $m->{"capture"}->[2];
                    $p = $m->{"to"};
                    $arg = Perlito5::Grammar::Expression::expand_list($arg)
                }
            }
            else {
                my $m = Perlito5::Grammar::Expression::list_parse($str, $p);
                if ($m->{"capture"} ne "*undef*") {
                    $arg = Perlito5::Grammar::Expression::expand_list($m->{"capture"});
                    $p = $m->{"to"}
                }
            }
            $m_name->{"capture"} = ["term", Perlito5::AST::Call::->new("method", $full_name, "invocant", Perlito5::Match::flat($invocant), "arguments", $arg)];
            $m_name->{"to"} = $p;
            return $m_name
        }
        if ($str->[$p] eq "=" && $str->[$p + 1] eq ">") {
            $m_name->{"capture"} = ["term", Perlito5::AST::Apply::->new("code", $name, "namespace", $namespace, "arguments", [], "bareword", 1)];
            $m_name->{"to"} = $p;
            return $m_name
        }
        my $sig = undef;
        {
            my $op = ($str->[$p]) . ($str->[$p + 1]);
            if ($op eq "!=" || $op eq "!~" || $op eq "=~") {;
                $sig = ''
            }
        }
        if (exists($Perlito5::PROTO->{$effective_name})) {
            $sig = $Perlito5::PROTO->{$effective_name};
            $namespace ||= $Perlito5::PKG_NAME
        }
        elsif ((!$namespace || $namespace eq "CORE") && exists($Perlito5::CORE_PROTO->{"CORE::" . $name})) {
            $effective_name = "CORE::" . $name;
            $sig = $Perlito5::CORE_PROTO->{$effective_name};
            my $core_global_name = "CORE::GLOBAL::" . $name;
            if (!$namespace && exists($Perlito5::CORE_GLOBAL_OVERRIDABLE->{$name}) && exists(&{$core_global_name})) {
                $namespace = "CORE::GLOBAL";
                $effective_name = $core_global_name;
                if (!exists($Perlito5::PROTO->{$core_global_name})) {;
                    $Perlito5::PROTO->{$core_global_name} = prototype(&{$core_global_name})
                }
            }
            my $local_name = $Perlito5::PKG_NAME . ("::" . $name);
            if (!$namespace && exists($Perlito5::CORE_OVERRIDABLE->{$name}) && exists(&{$local_name})) {
                $namespace = ${$Perlito5::PKG_NAME};
                $effective_name = $local_name;
                if (!exists($Perlito5::PROTO->{$local_name})) {;
                    $Perlito5::PROTO->{$local_name} = prototype(&{$local_name})
                }
            }
        }
        else {
            my $m = Perlito5::Grammar::Number::val_version($str, $pos);
            if ($m) {
                $m->{"capture"} = ["term", $m->{"capture"}];
                return $m
            }
        }
        if ($str->[$p] eq "-" && $str->[$p + 1] eq ">") {
            if ($is_subroutine_name) {;
                $m_name->{"capture"} = ["term", Perlito5::AST::Apply::->new("arguments", [], "code", $name, "namespace", $namespace)]
            }
            else {;
                $m_name->{"capture"} = ["term", Perlito5::AST::Var::->new("name", '', "namespace", $full_name, "sigil", "::")]
            }
            $m_name->{"to"} = $p;
            return $m_name
        }
        if (defined($sig) && $sig eq '') {
            my $expr = $Perlito5::CONSTANT{$namespace . "::" . $name};
            if ($expr) {
                if ($str->[$p] eq "(") {
                    $p++;
                    my $m = Perlito5::Grammar::Space::ws($str, $p);
                    if ($m) {;
                        $p = $m->{"to"}
                    }
                    if ($str->[$p] ne ")") {;
                        Perlito5::Compiler::error("Too many arguments for " . $namespace . "::" . $name)
                    }
                    $p++
                }
                $m_name->{"capture"} = ["term", $expr];
                $m_name->{"to"} = $p;
                return $m_name
            }
        }
        my $has_paren = 0;
        if (defined($sig)) {
            my $arg_index = 1;
            my $optional = 0;
            my @args;
            my $sig_part = substr($sig, 0, 1);
            my $m;
            my $capture;
            if ($sig_part eq "&") {
                $m = Perlito5::Grammar::Space::ws($str, $p);
                $m && ($p = $m->{"to"});
                if ($str->[$p] ne "(") {
                    $sig = substr($sig, 1);
                    $m = Perlito5::Grammar::Bareword::prototype_is_ampersand($str, $p);
                    $m && ($capture = $m->{"capture"});
                    if (!$m) {;
                        Perlito5::Compiler::error("Type of arg " . $arg_index . " to " . $name . " must be block or sub {}")
                    }
                    $p = $m->{"to"};
                    push(@args, $capture)
                }
            }
            if (substr($sig, 0, 1) eq ";" && $str->[$p] eq "/" && $str->[$p + 1] eq "/") {
                $m_name->{"capture"} = ["term", Perlito5::AST::Apply::->new("code", $name, "namespace", $namespace, "arguments", [], "bareword", 1)];
                $m_name->{"to"} = $p;
                return $m_name
            }
            if ($sig eq '') {
                if ($str->[$p] eq "(") {
                    $p++;
                    $has_paren = 1;
                    my $m = Perlito5::Grammar::Space::ws($str, $p);
                    if ($m) {;
                        $p = $m->{"to"}
                    }
                    if ($str->[$p] ne ")") {;
                        Perlito5::Compiler::error("syntax error near ", join('', @{$str}[$pos .. $pos + 10]))
                    }
                    $p++
                }
                if ($name eq "__FILE__") {;
                    $m_name->{"capture"} = ["term", Perlito5::AST::Buf::->new("buf", $Perlito5::FILE_NAME)]
                }
                elsif ($name eq "__LINE__") {;
                    $m_name->{"capture"} = ["term", Perlito5::AST::Int::->new("int", $Perlito5::LINE_NUMBER)]
                }
                else {;
                    $m_name->{"capture"} = ["term", Perlito5::AST::Apply::->new("code", $name, "namespace", $namespace, "arguments", \@args, "bareword", ($has_paren == 0))]
                }
                $m_name->{"to"} = $p;
                return $m_name
            }
            if ($sig eq "_" || $sig eq "\$" || $sig eq "+" || $sig eq ";\$") {
                my $m;
                my $arg;
                if ($str->[$p] eq "(") {
                    $m = Perlito5::Grammar::Expression::term_paren($str, $p);
                    if (!$m) {;
                        return $m
                    }
                    $p = $m->{"to"};
                    $has_paren = 1;
                    $arg = $m->{"capture"}->[2];
                    $arg = Perlito5::Grammar::Expression::expand_list($arg);
                    my $v = shift(@{$arg});
                    @{$arg} && Perlito5::Compiler::error("Too many arguments for " . $name);
                    $arg = $v
                }
                else {
                    $m = Perlito5::Grammar::Expression::argument_parse($str, $p);
                    $arg = $m->{"capture"};
                    if ($arg eq "*undef*") {;
                        $arg = undef
                    }
                    elsif (ref($arg) eq "Perlito5::AST::Apply" && $arg->{"code"} eq "circumfix:<( )>") {
                        my $v = shift(@{$arg->{"arguments"}});
                        @{$arg->{"arguments"}} && Perlito5::Compiler::error("Too many arguments for " . $name);
                        $arg = $v
                    }
                }
                if (defined($arg)) {
                    push(@args, $arg);
                    $has_paren = 1
                }
                else {
                    $sig eq "\$" && Perlito5::Compiler::error("Not enough arguments for " . $name);
                    $sig eq "_" && push(@args, Perlito5::AST::Var::->new("namespace", '', "name", "_", "sigil", "\$"))
                }
                my $ast = Perlito5::AST::Apply::->new("code", $name, "namespace", $namespace, "arguments", \@args, "bareword", ($has_paren == 0));
                if ($name eq "eval" && !$namespace) {
                    $ast->{"_scope"} = Perlito5::Grammar::Scope::get_snapshot($Perlito5::CLOSURE_SCOPE);
                    $ast->{"_scalar_hints"} = ${^H};
                    $ast->{"_hash_hints"} = {%{^H}, }
                }
                $m->{"capture"} = ["term", $ast];
                return $m
            }
            if ($sig eq ";\@" || $sig eq "\@") {
                if ($str->[$p] eq "(") {
                    $m = Perlito5::Grammar::Expression::term_paren($str, $p);
                    $has_paren = 1;
                    my $arg = $m->{"capture"}->[2];
                    $arg = Perlito5::Grammar::Expression::expand_list($arg);
                    push(@args, @{$arg})
                }
                else {
                    $m = Perlito5::Grammar::Expression::list_parse($str, $p);
                    my $arg = $m->{"capture"};
                    if ($arg ne "*undef*") {
                        $arg = Perlito5::Grammar::Expression::expand_list($arg);
                        push(@args, @{$arg})
                    }
                }
                my $ast = Perlito5::AST::Apply::->new("code", $name, "namespace", $namespace, "arguments", \@args, "bareword", ($has_paren == 0));
                $m->{"capture"} = ["term", $ast];
                return $m
            }
            if ($sig eq "*") {}
        }
        if ($str->[$p] eq "(") {
            $m = Perlito5::Grammar::Expression::term_paren($str, $p);
            if (!$m) {;
                return $m
            }
            my $arg = $m->{"capture"}->[2];
            $arg = Perlito5::Grammar::Expression::expand_list($arg);
            if ($namespace eq '' || $namespace eq "CORE") {
                if ($name eq "print" || $name eq "say") {;
                    if (@{$arg} == 0) {;
                        push(@{$arg}, Perlito5::AST::Var::->new("namespace", '', "name", "_", "sigil", "\$"))
                    }
                }
                if ($name eq "split") {
                    if (@{$arg} == 0) {;
                        push(@{$arg}, Perlito5::AST::Buf::->new("buf", " "))
                    }
                    if (@{$arg} == 1) {;
                        push(@{$arg}, Perlito5::AST::Var::->new("namespace", '', "name", "_", "sigil", "\$"))
                    }
                }
            }
            $m->{"capture"} = ["term", Perlito5::AST::Apply::->new("code", $name, "namespace", $namespace, "arguments", $arg, "proto", $sig)];
            return $m
        }
        my $m_list = Perlito5::Grammar::Expression::list_parse($str, $p);
        my $list = $m_list->{"capture"};
        if ($list ne "*undef*") {
            my $param_list = Perlito5::Grammar::Expression::expand_list($list);
            if (${^H} & $Perlito5::STRICT_SUBS) {;
                for my $i (0 .. $#{$param_list}) {
                    my $arg = $param_list->[$i];
                    if (ref($arg) eq "Perlito5::AST::Apply" && $arg->{"bareword"} && $arg->{"_not_a_subroutine"}) {
                        my $name = $arg->{"code"};
                        my $namespace = $arg->{"namespace"};
                        if ($sig && (substr($sig, $i, 1) eq "*" || substr($sig, $i, 2) eq ";*")) {}
                        else {;
                            Perlito5::Compiler::error("Bareword \"" . ($namespace ? $namespace . "::" : '') . $name . "\" not allowed while \"strict subs\" in use")
                        }
                    }
                }
            }
            $m_name->{"capture"} = ["postfix_or_term", "funcall", $namespace, $name, $param_list];
            $m_name->{"to"} = $m_list->{"to"};
            return $m_name
        }
        if ($namespace eq '' || $namespace eq "CORE") {
            if ($name eq "print" || $name eq "say") {
                $m_name->{"capture"} = ["term", Perlito5::AST::Apply::->new("code", $name, "namespace", $namespace, "arguments", [Perlito5::AST::Var::->new("namespace", '', "name", "_", "sigil", "\$")])];
                return $m_name
            }
            if ($name eq "split" && ($namespace eq '' || $namespace eq "CORE")) {
                $m_name->{"capture"} = ["term", Perlito5::AST::Apply::->new("code", $name, "namespace", $namespace, "arguments", [Perlito5::AST::Buf::->new("buf", " "), Perlito5::AST::Var::->new("namespace", '', "name", "_", "sigil", "\$")])];
                return $m_name
            }
        }
        if (${^H} & $Perlito5::STRICT_SUBS) {
            my $m = Perlito5::Grammar::Space::opt_ws($str, $p);
            my $p = $m->{"to"};
            if ($str->[$p] eq ":") {}
            elsif (!(exists($Perlito5::PROTO->{$effective_name}) || ((!$namespace || $namespace eq "CORE") && exists($Perlito5::CORE_PROTO->{"CORE::" . $name})))) {
                $m_name->{"capture"} = ["postfix_or_term", "funcall_no_params", Perlito5::AST::Apply::->new("code", $name, "namespace", $namespace, "arguments", [], "bareword", 1, "_not_a_subroutine", 1)];
                return $m_name
            }
        }
        $m_name->{"capture"} = ["postfix_or_term", "funcall_no_params", Perlito5::AST::Apply::->new("code", $name, "namespace", $namespace, "arguments", [], "bareword", 1)];
        return $m_name
    }
    sub Perlito5::Grammar::Bareword::prototype_is_ampersand {
        my $str = $_[0];
        my $pos = $_[1];
        my $MATCH = {"str" => $str, "from" => $pos, "to" => $pos, };
        my $tmp = ((do {
            my $tmp161 = $MATCH->{"to"};
            (((("s" eq $str->[($MATCH->{"to"}) + 0]) && ("u" eq $str->[($MATCH->{"to"}) + 1]) && ("b" eq $str->[($MATCH->{"to"}) + 2]) && ($MATCH->{"to"} += 3)) && (do {
                my $m2 = Perlito5::Grammar::Space::opt_ws($str, $MATCH->{"to"});
                if ($m2) {
                    $MATCH->{"to"} = $m2->{"to"};
                    1
                }
                else {;
                    0
                }
            }) && (do {
                my $m2 = Perlito5::Grammar::Block::anon_sub_def($str, $MATCH->{"to"});
                if ($m2) {
                    $MATCH->{"to"} = $m2->{"to"};
                    $MATCH->{"Perlito5::Grammar::Block::anon_sub_def"} = $m2;
                    1
                }
                else {;
                    0
                }
            }) && (do {
                $MATCH->{"capture"} = Perlito5::Match::flat($MATCH->{"Perlito5::Grammar::Block::anon_sub_def"});
                1
            }))) || ($MATCH->{"to"} = $tmp161, ((do {
                my $m2 = Perlito5::Grammar::block($str, $MATCH->{"to"});
                if ($m2) {
                    $MATCH->{"to"} = $m2->{"to"};
                    $MATCH->{"Perlito5::Grammar::block"} = $m2;
                    1
                }
                else {;
                    0
                }
            }) && (do {
                $MATCH->{"capture"} = Perlito5::AST::Sub::->new("attributes", [], "block", Perlito5::Match::flat($MATCH->{"Perlito5::Grammar::block"}), "name", undef, "namespace", undef, "sig", undef);
                1
            }))) || ($MATCH->{"to"} = $tmp161, ((do {
                my $tmp = $MATCH;
                $MATCH = {"from" => $tmp->{"to"}, "to" => $tmp->{"to"}, };
                my $res = ((("\\" eq $str->[($MATCH->{"to"}) + 0]) && ("\\" eq $str->[($MATCH->{"to"}) + 1]) && ($MATCH->{"to"} += 2)) && (do {
                    my $m2 = Perlito5::Grammar::Space::opt_ws($str, $MATCH->{"to"});
                    if ($m2) {
                        $MATCH->{"to"} = $m2->{"to"};
                        1
                    }
                    else {;
                        0
                    }
                }) && (("&" eq $str->[($MATCH->{"to"}) + 0]) && ($MATCH->{"to"} += 1)));
                $MATCH = $tmp;
                $res ? 1 : 0
            }) && (do {
                my $m2 = Perlito5::Grammar::Expression::argument_parse($str, $MATCH->{"to"});
                if ($m2) {
                    $MATCH->{"to"} = $m2->{"to"};
                    $MATCH->{"Perlito5::Grammar::Expression::argument_parse"} = $m2;
                    1
                }
                else {;
                    0
                }
            }) && (do {
                $MATCH->{"capture"} = Perlito5::Match::flat($MATCH->{"Perlito5::Grammar::Expression::argument_parse"});
                1
            })))
        }));
        $tmp ? $MATCH : undef
    }
    1
}
;1
