parrotcode: Untitled | |
Contents | Language Implementations | Pipp |
class Pipp::Grammar::Actions;
method TOP($/) { my $past := PAST::Stmts.new( :node($/) ); for $<sea_or_code> { $past.push( $($_) ); }
make $past;
}
method sea_or_code($/,$key) { make $( $/{$key} ); }
# The sea, HTML, surrounding the island, code, is printed out method SEA($/) { make PAST::Op.new( PAST::Val.new( :value(~$/), :returns('PhpString') ), :name('echo'), :node($/) ); }
method code_tp1($/) { my $past := PAST::Stmts.new( :node($/) ); for $<statement> { $past.push( $($_) ); }
make $past;
}
method code_tp2($/) { my $past := PAST::Stmts.new( :node($/) ); for $<statement> { $past.push( $($_) ); }
make $past;
}
method block($/) { my $past := PAST::Stmts.new( :node($/) ); for $<statement> { $past.push( $($_) ); }
make $past;
}
method statement($/,$key) { make $( $/{$key} ); }
method inline_sea_tp1($/) { make PAST::Op.new( PAST::Val.new( :value(~$<SEA_empty_allowed>), :returns('PhpString') ), :name('echo'), :node($/) ); }
method echo_statement($/) { my $past := $( $<arguments> ); $past.name( 'echo' );
make $past;
}
method expression_statement($/) { make $( $<expression> ); }
method function_call($/) { my $past := $( $<arguments> ); $past.name( ~$<FUNCTION_NAME> );
make $past;
}
method method_call($/) { my $past := PAST::Op.new( :name( ~$<METHOD_NAME> ), :pasttype( 'callmethod' ), :name( ~$<METHOD_NAME> ), $( $<var> ) );
make $past;
}
method constructor_call($/) { my $past := PAST::Op.new( :name( 'new' ), :pasttype( 'callmethod' ), PAST::Var.new( :name( ~$<CLASS_NAME> ), :scope( 'package' ), ) );
make $past;
}
method constant($/) { make PAST::Op.new( :name('constant'), PAST::Val.new( :returns('PhpString'), :value( ~$<CONSTANT_NAME> ), ) ); }
method arguments($/) { my $past := PAST::Op.new( :pasttype('call'), :node($/) ); for $<expression> { $past.push($($_)); }
make $past;
}
method if_statement($/) { my $past := PAST::Op.new( $( $<expression> ), $( $<block> ), :pasttype('if'), :node($/) ); for $<else_clause> { $past.push( $( $_ ) ); }
make $past;
}
method var_assign($/) { make PAST::Op.new( $( $<var> ), $( $<expression> ), :pasttype('bind'), ); }
method array_elem($/) { my $past_var_name := $( $<VAR_NAME> ); $past_var_name.scope('package'); $past_var_name.viviself('PhpArray');
make PAST::Var.new(
$past_var_name,
$( $<expression> ),
:scope('keyed'),
:viviself('Undef'),
:lvalue(1)
);
}
method var($/,$key) { make $( $/{$key} ); }
method VAR_NAME($/) { make PAST::Var.new( :scope('package'), :name(~$/), :viviself('Undef'), :lvalue(1) ); }
method this($/) { make PAST::Op.new( :inline( "%r = self" ) ); }
method else_clause($/) { make $( $<block> ); }
method while_statement($/) { my $cond := $( $<expression> ); my $block := $( $<block> );
make PAST::Op.new( $cond,
$block,
:pasttype('while'),
:node($/) );
}
method for_statement($/) { my $init := $( $<var_assign> ); my $cond := $( $<expression>[0] ); my $work := PAST::Stmts.new( $( $<block> ), $( $<expression>[1] ) );
my $while := PAST::Op.new(
$cond,
$work,
:pasttype('while'),
);
make PAST::Stmts.new( $init, $while );
}
# Handle the operator precedence table. method expression($/, $key) { if ($key eq 'end') { make $($<expr>); } else { my $past := PAST::Op.new( :name($<type>), :pasttype($<top><pasttype>), :pirop($<top><pirop>), :lvalue($<top><lvalue>), :node($/) ); for @($/) { $past.push( $($_) ); } make $past; } }
method term($/,$key) { make $( $/{$key} ); }
method literal($/,$key) { make $( $/{$key} ); }
method TRUE($/) { make PAST::Val.new( :value( 1 ), :returns('PhpBoolean'), :node($/) ); }
method FALSE($/) { make PAST::Val.new( :value( 0 ), :returns('PhpBoolean'), :node($/) ); }
method NULL($/) { make PAST::Val.new( :value( 0 ), :returns('PhpUndef'), :node($/) ); }
method INTEGER($/) { make PAST::Val.new( :value( ~$/ ), :returns('PhpInteger'), :node($/) ); }
method NUMBER($/) { make PAST::Val.new( :value( +$/ ), :returns('PhpFloat'), :node($/) ); }
method function_definition($/) {
# note that $<param_list> creates a new PAST::Block.
my $past := $( $<param_list> );
$past.name( ~$<FUNCTION_NAME> );
$past.control('return_pir');
$past.push( $( $<block> ) );
make $past;
}
method member_definition($/) { make PAST::Op.new( $( $<var> ), $( $<literal> ), :pasttype('bind'), ); }
method method_definition($/) {
# note that $<param_list> creates a new PAST::Block.
my $past := $( $<param_list> );
$past.name( ~$<METHOD_NAME> );
$past.blocktype( 'method' );
$past.control('return_pir');
$past.push( $( $<block> ) );
make $past;
}
method param_list($/) {
my $past := PAST::Block.new(
:blocktype('declaration'),
:node($/)
);
for $<VAR_NAME> {
my $param := $( $_ );
$param.scope('parameter');
$past.push($param);
# enter the parameter as a lexical into the block's symbol table
$past.symbol(
:scope('lexical'),
$param.name()
);
}
make $past;
}
method class_definition($/) { my $past := PAST::Block.new( :node($/), :blocktype('declaration'), :namespace( $<CLASS_NAME><ident> ), :pirflags( ':init :load' ), :lexical( 0 ), PAST::Stmts.new( PAST::Op.new( :inline( "$P0 = get_hll_global 'P6metaclass'\n $P1 = split '::', '" ~ $<CLASS_NAME> ~ "'\n push_eh subclass_done\n $P2 = $P0.'new_class'($P1)\n pop_eh\n subclass_done:\n" ), :pasttype( 'inline' ) ) ) ); for $<method_definition> { $past.push( $($_) ); }
make $past;
}
method quote($/) { make $( $<quote_expression> ); }
method quote_expression($/, $key) { my $past; if $key eq 'quote_regex' { our $?NS; $past := PAST::Block.new( $<quote_regex>, :compiler('PGE::Perl6Regex'), :namespace($?NS), :blocktype('declaration'), :node( $/ ) ); } elsif $key eq 'quote_concat' { if +$<quote_concat> == 1 { $past := $( $<quote_concat>[0] ); } else { $past := PAST::Op.new( :name('list'), :pasttype('call'), :node( $/ ) ); for $<quote_concat> { $past.push( $($_) ); } } } make $past; }
method quote_concat($/) { my $terms := +$<quote_term>; my $count := 1; my $past := $( $<quote_term>[0] ); while ($count != $terms) { $past := PAST::Op.new( $past, $( $<quote_term>[$count] ), :pirop('n_concat'), :pasttype('pirop') ); $count := $count + 1; } make $past; }
method quote_term($/, $key) { my $past; if ($key eq 'literal') { $past := PAST::Val.new( :value( ~$<quote_literal> ), :returns('PhpString'), :node($/) ); } else { $past := $( $/{ $key } ); }
make $past;
}
method curly_interpolation($/) { make $( $<var> ); }
# Local Variables: # mode: cperl # cperl-indent-level: 4 # fill-column: 100 # End: # vim: expandtab shiftwidth=4:
|