parrotcode: Untitled | |
Contents | Language Implementations | ChitChat |
class ChitChat::Grammar::Actions;
method TOP($/) { my $past := PAST::Block.new( :blocktype('declaration'), :node( $/ ) ); for $<exprs> { $past.push( $( $_ ) ); } make $past; }
method block($/) { my $past := PAST::Block.new( :blocktype('declaration'), :node($/) ); for $<id> { my $param := $( $_ ); $param.isdecl(1); $param.scope('parameter'); $past.push($param); } if $<temps> { my $temps := $( $<temps>[0] ); $past.push($temps); }
$past.push( $( $<exprs> ) );
make $past;
}
method method($/) { my $past := $( $<message> ); ## todo: pragma
if $<temps> {
$past.push( $( $<temps>[0] ) );
}
$past.push( $( $<exprs> ) );
make $past;
}
method message($/, $key) { if $key eq 'id' { my $name := $( $<id> ); make PAST::Block.new( :name($name), :node($/) ); } elsif $key eq 'binsel' { ## create a new block for a binary operator; stick to ## naming habit in other languages ('infix:...'). make PAST::Block.new( :name('infix:' ~ ~$<binsel>), :node($/) ); } elsif $key eq 'keysel' { my $name := ""; for $<keysel> { $name := $name ~ ~$_; } my $past := PAST::Block.new( :name($name), :node($/) );
for $<id> {
my $param := $( $_ );
$param.scope('parameter');
$past.push($param);
}
make $past;
}
}
method temps($/) { my $past := PAST::Stmts.new( :node($/) ); for $<id> { my $temp := $( $_ ); $temp.scope('lexical'); $temp.isdecl(1); $past.push( $temp ); } make $past; }
method exprs($/) { my $past := PAST::Stmts.new(); for $<expr> { $past.push( $( $_ ) ); } make $past; }
method expr($/) { # for $<id> { # $( $_ ); # } make $( $<expr2> ); }
method expr2($/,$key) { my $past := $( $/{$key} ); if $key eq 'msgexpr' { #my $statlist := PAST::Stmts.new(); #for $<cascade> { # my $stat := $( $_ ); # $stat.unshift($past); # $statlist.push($stat); #} #make $statlist; make $past; } else { make $past; } }
method cascade($/,$key) { make $( $/{$key} ); }
method msgexpr($/,$key) { make $( $/{$key} ); }
method keyexpr($/) { my $past := PAST::Op.new( :pasttype('callmethod') ); $past.push( PAST::Var.new( :name( $( $<keyexpr2>).name() ), :scope('package') ) ); my @args := $( $<keymsg> ); my $name := ''; while +@args { $name := $name ~ ~@args.shift(); $past.push( @args.shift() ); } $past.name($name); make $past; }
method keyexpr2($/, $key) { make $( $/{$key} ); }
method keymsg($/) { my @past; my $num := +$<keysel>; my $i := 0; while $i < $num { @past.push( ~$<keysel>[$i] ); @past.push( $($<keyexpr2>[$i]) ); $i++; } make @past; }
method binexpr($/) { my $past := $( $<primary> ); for $<binmsg> { my $call := $( $_ ); $call.unshift($past); $past := $call; } make $past; }
method binmsg($/) { my $past := PAST::Op.new( :name('infix:' ~ ~$<binsel>), :pasttype('call') ); $past.push( $( $<primary> ) ); make $past; }
method unaryexpr($/) { make $( $<unit> ); }
method primary($/,$key) { make $( $<unit> ); }
method unit($/,$key) { make $( $/{$key} ); }
method literal($/,$key) { make $( $/{$key} ); }
method arrayelem($/,$key) { make $( $/{$key} ); }
method number($/) { make PAST::Val.new( :value(~$/), :returns('Float') ); }
method string($/) { make PAST::Val.new( :value(~$<text>), :returns('String') ); }
method id($/) { make PAST::Var.new( :name(~$/), :scope('package'), :node($/) ); }
# Local Variables: # mode: cperl # cperl-indent-level: 4 # fill-column: 100 # End: # vim: expandtab shiftwidth=4:
|