shakespeare-parrot / src / parser / actions.pm

class z2::Grammar::Actions;

method TOP($/) {
  my $past := PAST::Block.new();
  for $<chardef> {
    $past.push( mkcall('declare', mkstr($_<character>)));
  }
  for $<act> {
    $past.push( $( $_ ) );
  }
  make $past;
}

sub mkstr($arg) {
  return PAST::Val.new(:value(""~$arg));
}
sub mkcall($name, $arg) {
  return PAST::Op.new($arg, :name($name), :pasttype('call'));
}
sub mkcall0($name) {
  return PAST::Op.new(:name($name), :pasttype('call'));
}

method assignment($/) {
  make mkcall('assign', $($<value>));
}

method events($/, $k) {
  make $( $/{$k} );
}

method act($/, $k) {
    my $past := PAST::Stmts.new();
    if $k eq 'open' {
      #fugly
      our $?ACT := ""~$<roman>;
      $past.push(PAST::Op.new( :inline("act_"~$?ACT~":")));
    }
    else {
      for $<scene> {
        $past.push( $( $_ ) );
      }
    }
    make $past;
}
method scene($/) {
    our $?ACT;
    my $past := PAST::Stmts.new(:name($<roman>));
    my $lbl := PAST::Op.new( 
      :inline("scene_"~$?ACT~"_"~$<roman>~":"));
    $past.push($lbl);
    for $<events> {
      $past.push( $( $_ ) );
    }
    make $past;
}

method branch($/) {
  our $?ACT;
  make PAST::Op.new(:inline("goto "~"scene_"~$?ACT~"_"~$<roman>));
}

method io($/,$k) {
  make mkcall0($k);
}


method line($/) {
    my $past := PAST::Stmts.new();
    $past.push(
      PAST::Op.new(
        PAST::Var.new(
          :name('the_speaker'),
          :scope('package')
        ),
        mkstr($<character>),
        :pasttype('bind')
      )
    );
    for $<sentence> {
      $past.push( $( $_ ) );
    }
    make $past;
}

method sentence($/, $key) {
  make $( $/{$key} );
}


method value($/, $key) {
  make $( $/{$key} );
}

method question($/, $k) {
  my $res;
  if $k eq 'eq' {
    $res := mkcall0( 'equal' );
  }
  else {
    $res := $($<comparison>);
  }
  for $<value> {
    $res.push( $( $_ ));
  }
  make $res;
}

method comparison($/,$k) {
    make mkcall0( $k );
}

method reference($/, $k) {
  if $k eq 'named_ref' {
    make mkcall('valueof',  mkstr($<character>));
  }
  elsif $k eq 'you_ref' {
    make mkcall('valueof', mkcall0('find_other_name'));
  }
  else {
    make mkcall('valueof', mkcall0('get_speaker_name'));
  }
}

method move($/, $k) {
  my $past := PAST::Stmts.new();
  if $<character> {
    for $<character> {
      my $res := mkcall($k, mkstr($_));
      $past.push($res);
    }
  }
  else {
    $past.push(mkcall0('exeunt_omnes'));
  } 
  make $past;
}

method immediate($/) {
  my $value := 1;
  if $<noun><negative_noun> {
    $value := -1;
  }
  elsif $<noun><nothing> {
    $value := 0;
  }
  for $<adjective> {
    unless $_<first_person_possessive> || $_<second_person_possessive> || $_<third_person_possessive> {
      $value:= $value*2;
    }
  }
  make PAST::Val.new( :value( $value ) );
}


method tap($/) {
  make mkcall('tap', $($<value>));
}

method memorize($/) {
  make mkcall('push', $($<value>));
}

method recall($/) {
  make mkcall0( 'pop' );
}

method plan($/) {
  make mkcall('plan', $($<value>));
}

method test($/, $k) {
  my $test := PAST::Var.new(:name('the_condition'),:scope('package'));
  make PAST::Op.new( $test, $($<sentence>), :pasttype($k));
}

method computation($/, $key) {
  make $( $/{$key} );
}

method unary($/, $k) {
  make mkcall($k, $($<value>));
}

method binary($/, $key) {
  my $res := PAST::Op.new(:pirop( $key ));
  for $<value> { $res.push( $( $_ )) }
  make $res;
}
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.