# Do not edit this file - Generated by Perlito5 9.011
{
    package main;
    package Perlito5::Grammar::Statement;
    use Perlito5::Macro;
    my @Statement_chars;
    my %Statement;
    sub Perlito5::Grammar::Statement::add_statement {
        my $name = shift;
        my $param = shift;
        $Statement{$name} = $param;
        unshift(@Statement_chars, scalar(@Statement_chars) + 1)
            while @Statement_chars < length($name)
    }
    sub Perlito5::Grammar::Statement::stmt_yadayada {
        my $str = $_[0];
        my $pos = $_[1];
        my $MATCH = {'str' => $str, 'from' => $pos, 'to' => $pos};
        my $tmp = ((('...' eq substr($str, $MATCH->{'to'}, 3) && ($MATCH->{'to'} = 3 + $MATCH->{'to'})) && (do {
            $MATCH->{'str'} = $str;
            $MATCH->{'capture'} = Perlito5::AST::Apply::->new('code' => 'die', 'namespace' => '', 'arguments' => [Perlito5::AST::Buf::->new('buf' => 'Unimplemented')]);
            1
        })));
        $tmp ? $MATCH : 0
    }
    sub Perlito5::Grammar::Statement::stmt_format {
        my $str = $_[0];
        my $pos = $_[1];
        my $MATCH = {'str' => $str, 'from' => $pos, 'to' => $pos};
        my $tmp = ((('format' eq substr($str, $MATCH->{'to'}, 6) && ($MATCH->{'to'} = 6 + $MATCH->{'to'})) && (do {
            my $m2 = Perlito5::Grammar::Space::ws($str, $MATCH->{'to'});
            if ($m2) {
                $MATCH->{'to'} = $m2->{'to'};
                1
            }
            else {
                0
            }
        }) && (do {
            my $pos1 = $MATCH->{'to'};
            (do {
                (do {
                    my $m2 = Perlito5::Grammar::full_ident($str, $MATCH->{'to'});
                    if ($m2) {
                        $MATCH->{'to'} = $m2->{'to'};
                        $MATCH->{'Perlito5::Grammar::full_ident'} = $m2;
                        1
                    }
                    else {
                        0
                    }
                })
            }) || (do {
                $MATCH->{'to'} = $pos1;
                (do {
                    $MATCH->{'str'} = $str;
                    $MATCH->{'Perlito5::Grammar::full_ident'} = 'STDOUT';
                    1
                })
            })
        }) && (do {
            $MATCH->{'str'} = $str;
            my $placeholder = Perlito5::AST::Apply::->new('code' => 'list:<.>', 'namespace' => '', 'arguments' => [Perlito5::AST::Apply::->new('code' => 'list:<.>', 'namespace' => '', 'arguments' => [])]);
            push(@Perlito5::Grammar::String::Here_doc, ['single_quote', $placeholder->{'arguments'}->[0]->{'arguments'}, '.']);
            $MATCH->{'capture'} = Perlito5::AST::Apply::->new('code' => 'p5:format', 'namespace' => '', 'arguments' => [Perlito5::Match::flat($MATCH->{'Perlito5::Grammar::full_ident'}), $placeholder]);
            1
        }) && (do {
            my $m2 = Perlito5::Grammar::Space::opt_ws($str, $MATCH->{'to'});
            if ($m2) {
                $MATCH->{'to'} = $m2->{'to'};
                1
            }
            else {
                0
            }
        }) && ('=' eq substr($str, $MATCH->{'to'}, 1) && ($MATCH->{'to'} = 1 + $MATCH->{'to'})) && (do {
            my $m2 = Perlito5::Grammar::Space::ws($str, $MATCH->{'to'});
            if ($m2) {
                $MATCH->{'to'} = $m2->{'to'};
                1
            }
            else {
                0
            }
        })));
        $tmp ? $MATCH : 0
    }
    sub Perlito5::Grammar::Statement::stmt_package {
        my $str = $_[0];
        my $pos = $_[1];
        my $MATCH = {'str' => $str, 'from' => $pos, 'to' => $pos};
        my $tmp = ((('package' eq substr($str, $MATCH->{'to'}, 7) && ($MATCH->{'to'} = 7 + $MATCH->{'to'})) && (do {
            my $m2 = Perlito5::Grammar::Space::ws($str, $MATCH->{'to'});
            if ($m2) {
                $MATCH->{'to'} = $m2->{'to'};
                1
            }
            else {
                0
            }
        }) && (do {
            my $m2 = Perlito5::Grammar::full_ident($str, $MATCH->{'to'});
            if ($m2) {
                $MATCH->{'to'} = $m2->{'to'};
                $MATCH->{'Perlito5::Grammar::full_ident'} = $m2;
                1
            }
            else {
                0
            }
        }) && (do {
            my $pos1 = $MATCH->{'to'};
            (do {
                ((do {
                    my $m2 = Perlito5::Grammar::Space::opt_ws($str, $MATCH->{'to'});
                    if ($m2) {
                        $MATCH->{'to'} = $m2->{'to'};
                        1
                    }
                    else {
                        0
                    }
                }) && (do {
                    $MATCH->{'str'} = $str;
                    my $name = Perlito5::Match::flat($MATCH->{'Perlito5::Grammar::full_ident'});
                    $MATCH->{'_package'} = $Perlito5::PKG_NAME;
                    $Perlito5::PACKAGES->{$name} = 1;
                    $Perlito5::PKG_NAME = $name;
                    1
                }) && (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->{'str'} = $str;
                    $MATCH->{'capture'} = Perlito5::AST::Block::->new('stmts' => [Perlito5::AST::Apply::->new('code' => 'package', 'arguments' => [], 'namespace' => Perlito5::Match::flat($MATCH->{'Perlito5::Grammar::full_ident'})), @{$MATCH->{'Perlito5::Grammar::block'}->{'capture'}->{'stmts'}}]);
                    $Perlito5::PKG_NAME = $MATCH->{'_package'};
                    1
                }))
            }) || (do {
                $MATCH->{'to'} = $pos1;
                (do {
                    $MATCH->{'str'} = $str;
                    my $name = Perlito5::Match::flat($MATCH->{'Perlito5::Grammar::full_ident'});
                    $Perlito5::PACKAGES->{$name} = 1;
                    $Perlito5::PKG_NAME = $name;
                    $MATCH->{'capture'} = Perlito5::AST::Apply::->new('code' => 'package', 'arguments' => [], 'namespace' => $name);
                    1
                })
            })
        })));
        $tmp ? $MATCH : 0
    }
    sub Perlito5::Grammar::Statement::exp_stmt {
        my $str = $_[0];
        my $pos = $_[1];
        for my $len (@Statement_chars) {
            my $term = substr($str, $pos, $len);
            if (exists($Statement{$term})) {
                my $m = $Statement{$term}->($str, $pos);
                $m && return $m
            }
        }
        return 0
    }
    my @Modifier_chars = (7, 6, 5, 4, 3, 2);
    my %Modifier = ('if' => 1, 'unless' => 1, 'when' => 1, 'for' => 1, 'foreach' => 1, 'while' => 1, 'until' => 1, 'given' => 1);
    sub Perlito5::Grammar::Statement::statement_modifier {
        my $str = $_[0];
        my $pos = $_[1];
        my $expression = $_[2];
        for my $len (@Modifier_chars) {
            my $term = substr($str, $pos, $len);
            if (exists($Modifier{$term})) {
                my $m = modifier($str, $pos + $len, $term, $expression);
                $m && return $m
            }
        }
        return 0
    }
    sub Perlito5::Grammar::Statement::modifier {
        my $str = $_[0];
        my $pos = $_[1];
        my $modifier = $_[2];
        my $expression = $_[3];
        my $modifier_exp = Perlito5::Grammar::Expression::exp_parse($str, $pos);
        if (!$modifier_exp) {
            die('Expected expression after ' . chr(39), Perlito5::Match::flat($modifier), chr(39))
        }
        if ($modifier eq 'if') {
            return {'str' => $str, 'from' => $pos, 'to' => $modifier_exp->{'to'}, 'capture' => Perlito5::AST::Apply::->new('arguments' => [Perlito5::Match::flat($modifier_exp), $expression], 'code' => 'infix:<&&>', 'namespace' => '')}
        }
        if ($modifier eq 'unless') {
            return {'str' => $str, 'from' => $pos, 'to' => $modifier_exp->{'to'}, 'capture' => Perlito5::AST::Apply::->new('arguments' => [Perlito5::Match::flat($modifier_exp), $expression], 'code' => 'infix:<||>', 'namespace' => '')}
        }
        if ($modifier eq 'when') {
            return {'str' => $str, 'from' => $pos, 'to' => $modifier_exp->{'to'}, 'capture' => Perlito5::AST::When::->new('cond' => Perlito5::Match::flat($modifier_exp), 'body' => $expression)}
        }
        if ($modifier eq 'while') {
            my $stmt = Perlito5::AST::While::->new('cond' => Perlito5::Match::flat($modifier_exp), 'body' => $expression);
            my $out = Perlito5::Macro::while_file($stmt);
            $out && ($stmt = $out);
            return {'str' => $str, 'from' => $pos, 'to' => $modifier_exp->{'to'}, 'capture' => $stmt}
        }
        if ($modifier eq 'until') {
            my $stmt = Perlito5::AST::While::->new('cond' => Perlito5::AST::Apply::->new('arguments' => [Perlito5::Match::flat($modifier_exp)], 'code' => 'prefix:<!>', 'namespace' => ''), 'body' => $expression);
            return {'str' => $str, 'from' => $pos, 'to' => $modifier_exp->{'to'}, 'capture' => $stmt}
        }
        if ($modifier eq 'for' || $modifier eq 'foreach') {
            return {'str' => $str, 'from' => $pos, 'to' => $modifier_exp->{'to'}, 'capture' => Perlito5::AST::For::->new('cond' => Perlito5::Match::flat($modifier_exp), 'body' => $expression, 'topic' => Perlito5::AST::Var::->new('namespace' => '', 'name' => '_', 'sigil' => '$'))}
        }
        die('Unexpected statement modifier ' . chr(39) . $modifier . chr(39))
    }
    sub Perlito5::Grammar::Statement::statement_parse {
        my $m = statement_parse_inner(@_);
        !@Perlito5::SCOPE_STMT && return $m;
        Perlito5::Grammar::Scope::check_variable_declarations();
        return $m
    }
    sub Perlito5::Grammar::Statement::statement_parse_inner {
        my $str = $_[0];
        my $pos = $_[1];
        my $res = exp_stmt($str, $pos);
        if ($res) {
            return $res
        }
        $res = Perlito5::Grammar::Expression::exp_parse($str, $pos);
        if (!$res) {
            return 
        }
        if (substr($str, $res->{'to'}, 1) eq ':' && $res->{'capture'}->isa('Perlito5::AST::Apply') && $res->{'capture'}->{'bareword'}) {
            my $label = $res->{'capture'}->{'code'};
            my $ws = Perlito5::Grammar::Space::opt_ws($str, $res->{'to'} + 1);
            my $stmt = statement_parse($str, $ws->{'to'});
            if ($stmt) {
                $stmt->{'capture'}->{'label'} = $label;
                return $stmt
            }
            $res->{'to'} = $ws->{'to'};
            $res->{'capture'} = Perlito5::AST::Apply::->new('arguments' => [], 'code' => 'undef', 'namespace' => '', 'label' => $label);
            return $res
        }
        my $modifier = statement_modifier($str, $res->{'to'}, Perlito5::Match::flat($res));
        my $p = $modifier ? $modifier->{'to'} : $res->{'to'};
        my $terminator = substr($str, $p, 1);
        $terminator ne ';' && $terminator ne '}' && $terminator ne '' && die('Number or Bareword found where operator expected');
        if (!$modifier) {
            return $res
        }
        return $modifier
    }
    Perlito5::Grammar::Statement::add_statement('...' => \&stmt_yadayada);
    Perlito5::Grammar::Statement::add_statement('package' => \&stmt_package);
    Perlito5::Grammar::Statement::add_statement('format' => \&stmt_format);
    1
}
;1
