AC-MrGamoo

 view release on metacpan or  search on metacpan

lib/AC/MrGamoo/Submit/Compile.pm  view on Meta::CPAN

sub get_code {
    my $me   = shift;
    my $name = shift;
    my $num  = shift;

    my $prog = $me->compile( $name, $num );
    return unless $prog;

    my $c = eval $prog;
    die $@ if $@;

    return $c;
}

sub _die {
    my $me  = shift;
    my $err = shift;

    if( $me->{_lineno} ){
        die "ERROR: $err\nfile: $me->{file} line: $me->{_lineno}\n$me->{_line}\n";
    }
    die "ERROR: $err\nfile: $me->{file}\n";
}

sub _next {
    my $me = shift;

    return unless @{ $me->{lines} };
    $me->{_line} = shift @{ $me->{lines} };
    $me->{_lineno} ++;
    $me->{_file_content} .= $me->{_line};
    return $me->{_line};
}

sub _compile {
    my $me = shift;

    while(1){
        my $line = $me->_next();
        last unless defined $line;
        chomp $line;

        # white, comment, or start
        $line =~ s/^%#.*//;
        $line =~ s/#.*//;
        next if $line =~ /^\s*$/;

        my($tag) = $line =~ m|^<%(.*)>\s*$|;
        my $d    = $COMPILE{$tag};

        if( $d->{tag} eq 'block'){
            $me->_add_block($tag, $me->_compile_block($tag));
        }
        elsif( $d->{tag} eq 'simple' ){
            $me->_add_block($tag, $me->_compile_block_simple($tag));
        }
        elsif( $d->{tag} eq 'config' ){
            $me->_add_config($tag, $me->_compile_config($tag));
        }
        else{
            $me->_die("syntax error");
        }
    }

    delete $me->{_lineno};
    delete $me->{_line};
    delete $me->{_fd};

    1;
}

sub _lineno_info {
    my $me  = shift;

    # should have the number of the _next_ line
    return sprintf "#line %d $me->{file}\n", $me->{_lineno} + 1;
}

sub _compile_block {
    my $me  = shift;
    my $tag = shift;

    my $b = AC::MrGamoo::Submit::Compile::Block->new();

    $b->{code} = $me->_lineno_info();

    while(1){
        my $line = $me->_next();
        $me->_die("end of file reached looking for end of $tag section") unless defined $line;
        last if $line =~ m|^</%$tag>\s*$|;

        my($tag) = $line =~ m|^<%(.*)>\s*$|;

        if( $BLOCK{$tag} eq 'simple' ){
            $b->{$tag} .= $me->_compile_block_simple( $tag );
            $b->{code} .= $me->_lineno_info();
        }elsif( $BLOCK{$tag} eq 'config' ){
            $b->{$tag} = $me->_compile_config( $tag );
        }elsif( $tag ){
            $me->_die("syntax error");

        }else{
            $b->{code} .= $line;
        }
    }

    return $b;
}

sub _compile_block_simple {
    my $me  = shift;
    my $tag = shift;

    my $b = $me->_lineno_info();

    while(1){
        my $line = $me->_next();
        $me->_die("end of file reached looking for end of $tag section") unless defined $line;
        last if $line =~ m|^</%$tag>\s*$|;
        $b .= $line;
    }

    return $b;
}

sub _compile_config {
    my $me  = shift;
    my $tag = shift;

    my $c = {};

    while(1){
        my $line = $me->_next();
        $me->_die("end of file reached looking for end of '$tag' section") unless defined $line;
        return $c if $line =~ m|^</%$tag>\s*$|;

        $line =~ s/^\s+//;
        $line =~ s/\s+$//;
        my($k, $v) = split /\s+=>\s*/, $line, 2;
        $c->{$k} = $v;
    }
}

sub _add_block {
    my $me  = shift;
    my $tag = shift;
    my $blk = shift;

    my $d = $COMPILE{$tag};

    if( $d->{multi} ){
        push @{$me->{content}{$tag}}, $blk;
    }else{
        $me->_die("redefinition of '$tag' section") if $me->{content}{$tag};
        $me->{content}{$tag} = $blk;
    }
}

sub add_config {
    my $me  = shift;



( run in 0.581 second using v1.01-cache-2.11-cpan-39bf76dae61 )