Author: kjs
Date: Tue Mar 25 09:29:30 2008
New Revision: 26534

Added:
   trunk/compilers/nqp/bootstrap/
   trunk/compilers/nqp/bootstrap/actions.pm   (contents, props changed)
Modified:
   trunk/MANIFEST

Log:
[nqp] add initial actions file for NQP, written in NQP. Update MANIFEST.

Modified: trunk/MANIFEST
==============================================================================
--- trunk/MANIFEST      (original)
+++ trunk/MANIFEST      Tue Mar 25 09:29:30 2008
@@ -1,7 +1,7 @@
 # ex: set ro:
 # $Id$
 #
-# generated by tools/dev/mk_manifest_and_skip.pl Mon Mar 24 18:17:42 2008 UT
+# generated by tools\dev\mk_manifest_and_skip.pl Tue Mar 25 16:27:43 2008 UT
 #
 # See tools/dev/install_files.pl for documentation on the
 # format of this file.
@@ -85,6 +85,7 @@
 compilers/json/test.pir                                     []
 compilers/nqp/README.pod                                    []
 compilers/nqp/TODO.pod                                      []
+compilers/nqp/bootstrap/actions.pm                          []
 compilers/nqp/nqp.pir                                       []
 compilers/nqp/src/Grammar.pg                                []
 compilers/nqp/src/Grammar/Actions.pir                       []

Added: trunk/compilers/nqp/bootstrap/actions.pm
==============================================================================
--- (empty file)
+++ trunk/compilers/nqp/bootstrap/actions.pm    Tue Mar 25 09:29:30 2008
@@ -0,0 +1,1044 @@
+# Copyright (C) 2007-2008, The Perl Foundation.
+# $Id$
+
+## Actions for the NQP compiler, written in NQP.
+## Some minor changes were made to the grammar, such as
+## removal of superfluous keys. This actions file must be
+## aligned to NQP's current grammar file, and some parts
+## should be finished, such as some built-in operators,
+## the for-statement seems broken, etc.
+##
+
+class NQP::Grammar::Actions;
+
+method TOP($/) {
+    my $past := $($<statement_block>);
+    $past.blocktype('declaration');
+    make $past;
+}
+##.sub 'TOP' :method
+##    .param pmc match
+##    .local pmc past
+##    $P0 = match['statement_block']
+##    past = $P0.'get_scalar'()
+##    past.'blocktype'('declaration')
+##    match.'result_object'(past)
+##.end
+
+
+#### Blocks and Statements ####
+
+method statement_block($/, $key) {
+    our $?BLOCK;
+    our @?BLOCK;
+    if ($key eq 'open') {
+        $?BLOCK := PAST::Block.new( PAST::Stmts.new( :node($/) ),
+                                    :blocktype('immediate'),
+                                    :node($/) );
+        @?BLOCK.unshift($?BLOCK);
+    }
+    else {
+        my $past := @?BLOCK.shift();
+        $?BLOCK := @?BLOCK[0];
+        $past.push($($<statement_list>));
+        make $past;
+    }
+}
+##.sub 'statement_block' :method
+##    .param pmc match
+##    .param string key
+##    if key == 'close' goto block_close
+##  block_open:
+##    .local pmc past
+##    $P1 = get_hll_global ['PAST'], 'Stmts'
+##    $P2 = $P1.'new'()
+##    $P0 = get_hll_global ['PAST'], 'Block'
+##    past = $P0.'new'($P2, 'blocktype'=>'immediate', 'node'=>match)
+##    set_global '$?BLOCK', past
+##    $P0 = get_global '@?BLOCK'
+##    unshift $P0, past
+##    .return ()
+##  block_close:
+##    $P0 = get_global '@?BLOCK'
+##    past = shift $P0
+##    $P1 = $P0[0]
+##    set_global '$?BLOCK', $P1
+##    $P2 = match['statement_list']
+##    $P3 = $P2.'get_scalar'()
+##    past.'push'($P3)
+##    match.'result_object'(past)
+##.end
+
+
+method statement_list($/) {
+    my $past := PAST::Stmts.new(:node($/));
+    for $<statement> {
+        $past.push($($_));
+    }
+    make $past;
+}
+##.sub 'statement_list' :method
+##    .param pmc match
+##    .local pmc past
+##    $P0 = get_hll_global ['PAST'], 'Stmts'
+##    past = $P0.'new'('node'=>match)
+##    $P1 = match['statement']
+##    if null $P1 goto iter_end
+##    .local pmc iter
+##    iter = new 'Iterator', $P1
+##  iter_loop:
+##    unless iter goto iter_end
+##    $P2 = shift iter
+##    $P2 = $P2.'get_scalar'()
+##    past.'push'($P2)
+##    goto iter_loop
+##  iter_end:
+##    match.'result_object'(past)
+##.end
+
+
+method statement($/, $key) {
+    make $($/{$key});
+}
+
+##.sub 'statement' :method
+##    .param pmc match
+##    .param string key
+##    $P0 = match[key]
+##    $P1 = $P0.'get_scalar'()
+##    match.'result_object'($P1)
+##.end
+
+
+method if_statement($/) {
+    my $cond := +$<EXPR> - 1;
+    my $past := PAST::Op.new( $( $<EXPR>[$cond] ),
+                              $( $<block>[$cond] ),
+                              :pasttype('if'),
+                              :node( $/ )
+                            );
+    if ( $<else> ) {
+        $past.push( $( $<else>[0] ) );
+    }
+    while ($cond != 0) {
+        $cond := $cond - 1;
+        $past := PAST::Op.new( $( $<EXPR>[$cond] ),
+                               $( $<block>[$cond] ),
+                               $past,
+                               :pasttype('if'),
+                               :node( $/ )
+                             );
+    }
+    make $past;
+}
+##.sub 'if_statement' :method
+##    .param pmc match
+##    .local pmc expr, block, past
+##    .local int cond
+##    cond = match['EXPR']
+##    cond -= 1
+##    bsr get_expr
+##    bsr get_block
+##    $P2 = get_hll_global ['PAST'], 'Op'
+##    past = $P2.'new'(expr, block, 'pasttype'=>'if', 'node'=>match)
+##
+##    $I0 = exists match['else']
+##    unless $I0 goto while
+##    block = match['else']
+##    block = block[0]
+##    block = block.'get_scalar'()
+##    past.'push'( block )
+##
+##  while:
+##    unless cond != 0 goto end_while
+##    cond -= 1
+##    bsr get_expr
+##    bsr get_block
+##    past = $P2.'new'(expr, block, past, 'pasttype'=>'if', 'node'=>match)
+##    goto while
+##
+##  end_while:
+##    goto end
+##
+##  get_expr:
+##    expr = match['EXPR']
+##    expr = expr[cond]
+##    expr = expr.'get_scalar'()
+##    ret
+##  get_block:
+##    block = match['block']
+##    block = block[cond]
+##    block = block.'get_scalar'()
+##    ret
+##  end:
+##    match.'result_object'(past)
+##.end
+
+
+method unless_statement($/) {
+    my $past := PAST::Op.new( $( $<EXPR> ),
+                              $( $<block> ),
+                              :pasttype('unless'),
+                              :node( $/ )
+                            );
+    make $past;
+}
+##.sub 'unless_statement' :method
+##    .param pmc match
+##    .local pmc expr, block, past
+##    expr = match['EXPR']
+##    expr = expr
+##    expr = expr.'get_scalar'()
+##    block = match['block']
+##    block = block
+##    block = block.'get_scalar'()
+##    $P0 = get_hll_global ['PAST'], 'Op'
+##    past = $P0.'new'(expr, block, 'pasttype'=>'unless', 'node'=>match)
+##    match.'result_object'(past)
+##.end
+
+
+method repeat_statement($/) {
+    make PAST::Op.new( $($<EXPR>),
+                       $($<block>),
+                       :pasttype( 'repeat_' ~ $<sym> ),
+                       :node( $/ )
+                     );
+}
+##.sub 'repeat_statement' :method
+##    .param pmc match
+##    $P1 = match['EXPR']
+##    $P1 = $P1.'get_scalar'()
+##    $P2 = match['block']
+##    $P2 = $P2.'get_scalar'()
+##    $S0 = match['sym']
+##    $S0 = concat 'repeat_', $S0
+##    $P0 = get_hll_global ['PAST'], 'Op'
+##    $P5 = $P0.'new'( $P1, $P2, 'pasttype'=>$S0, 'node'=>match)
+##    match.'result_object'($P5)
+##.end
+
+
+method while_statement($/) {
+    make PAST::Op.new( $($<EXPR>),
+                       $($<block>),
+                       :pasttype( ~$<sym> ),
+                       :node( $/ )
+                     );
+}
+##.sub 'while_statement' :method
+##    .param pmc match
+##    $P1 = match['EXPR']
+##    $P1 = $P1.'get_scalar'()
+##    $P2 = match['block']
+##    $P2 = $P2.'get_scalar'()
+##    $S0 = match['sym']
+##    $P0 = get_hll_global ['PAST'], 'Op'
+##    $P5 = $P0.'new'( $P1, $P2, 'pasttype'=>$S0, 'node'=>match)
+##    match.'result_object'($P5)
+##.end
+
+
+method for_statement($/) {
+    my $block := $( $<block> );
+    #$block.blocktype('sub');
+    $block.blocktype('immediate');
+    $block.symbol(:name('$_'), :scope('lexical'));
+    my $topic_var := PAST::Var.new(:name('$_'), :scope('parameter'));
+    $block[0].push($topic_var);
+    my $past := PAST::Op.new($($<EXPR>),
+                             $($<block>),
+                             :pasttype(~$<sym>),
+                             :node($/));
+    make $past;
+}
+##.sub 'for_statement' :method
+##    .param pmc match
+##    .local pmc block, past
+##    $P0  = match['EXPR']
+##    $P0  = $P0.'get_scalar'()
+##    $P1  = match['block']
+##    block = $P1.'get_scalar'()
+##    block.'blocktype'('sub')
+##    .local pmc params, topic_var
+##    params = block[0]
+##    $P3 = get_hll_global ['PAST'], 'Var'
+##    topic_var = $P3.'new'('name'=>'$_', 'scope'=>'parameter')
+##    params.'push'(topic_var)
+##    block.'symbol'('$_', 'scope'=>'lexical')
+##    $P2  = get_hll_global ['PAST'], 'Op'
+##    $S1  = match['sym']
+##    past = $P2.'new'($P0, block, 'pasttype'=>$S1, 'node'=>match)
+##    match.'result_object'(past)
+##.end
+
+
+method make_statement($/) {
+    make PAST::Op.new( PAST::Var.new( :name('$/'),
+                                      :scope('lexical') ),
+                       $($<EXPR>),
+                       :name('result_object'),
+                       :pasttype('callmethod') );
+}
+##.sub 'make_statement' :method
+##    .param pmc match
+##    $P0 = get_hll_global ['PAST'], 'Var'
+##    $P1 = $P0.'new'( 'name'=>'$/', 'scope'=>'lexical' )
+##    $P2 = match['EXPR']
+##    $P3 = $P2.'get_scalar'()
+##    $P4 = get_hll_global ['PAST'], 'Op'
+##    $P5 = $P4.'new'($P1, $P3, 'name'=>'result_object', 
'pasttype'=>'callmethod')
+##    match.'result_object'($P5)
+##.end
+
+
+method inline_pir_statement($/, $key) {
+    my $inline;
+    if ($key eq 'quote')   { $inline := ~$($<quote><string_literal>) }
+    if ($key eq 'heredoc') { $inline := ~$/<text> }
+
+    make PAST::Op.new( :inline( $inline ),
+                       :pasttype('inline'),
+                       :node( $/ )
+                     );
+}
+##.sub 'inline_pir_statement' :method
+##    .param pmc match
+##    .param pmc key
+##    .local pmc inline
+##    if key != 'quote' goto not_quote
+##    $P0 = match['quote']
+##    $P0 = $P0['string_literal']
+##    inline = $P0.'get_scalar'()
+##    goto make
+##  not_quote:
+##    if key != 'heredoc' goto not_heredoc
+##    $P0 = match['text']
+##    inline = $P0.'text'()
+##  not_heredoc:
+##  make:
+##    $P1 = get_hll_global ['PAST'], 'Op'
+##    $P2 = $P1.'new'( 'inline'=>inline, 'pasttype'=>'inline', 'node'=>match)
+##    match.'result_object'($P2)
+##.end
+
+
+method block($/) {
+    make $($<statement_block>);
+}
+##.sub 'block' :method
+##    .param pmc match
+##    $P0 = match['statement_block']
+##    $P0 = $P0.'get_scalar'()
+##    match.'result_object'($P0)
+##.end
+
+
+#### Subroutine and method definitions ####
+
+method routine_def($/) {
+    my $past := $($<block>);
+    $past.name(~$<ident>);
+    $past.node($/);
+    $past.blocktype('declaration');
+    my $params := $past[0];
+    if $<declarator> eq 'method' {
+        $past.blocktype('method');
+    }
+    for $<signature>[0] {
+        my $parameter := $($_<parameter>);
+        $past.symbol($parameter.name(), :scope('lexical'));
+        $params.push($parameter);
+    }
+    make $past;
+}
+##.sub 'routine_def' :method
+##    .param pmc match
+##    .local pmc past
+##    $P0 = match['block']
+##    past = $P0.'get_scalar'()
+##    $S0 = match['ident']
+##    past.'name'($S0)
+##    past.'node'(match)
+##    past.'blocktype'('declaration')
+##    .local pmc params
+##    params = past[0]
+##    $S0 = match['declarator']
+##    if $S0 != 'method' goto add_signature
+##    past.'blocktype'('method')
+##  add_signature:
+##    $P0 = match['signature']
+##    $P0 = $P0[0]
+##    unless $P0 goto param_end
+##    .local pmc iter
+##    iter = new 'Iterator', $P0
+##  param_loop:
+##    unless iter goto param_end
+##    $P1 = shift iter
+##    .local pmc parameter
+##    $P2 = $P1['parameter']
+##    parameter = $P2.'get_scalar'()
+##    $S0 = parameter.'name'()
+##    past.'symbol'($S0, 'scope'=>'lexical')
+##    params.'push'(parameter)
+##    goto param_loop
+##  param_end:
+##    match.'result_object'(past)
+##.end
+
+
+method parameter($/, $key) {
+    my $past := $( $<param_var> );
+    my $sigil := $<param_var><sigil>;
+    if $key eq 'slurp' {              # slurpy
+        $past.slurpy( $sigil eq '@' || $sigil eq '%' );
+        $past.named( $sigil eq '%' );
+    }
+    else {
+        if $<named> eq ':' {          # named
+            $past.named(~$<param_var><ident>);
+            if $<quant> ne '!' {      #  required (optional is default)
+                $past.viviself('Undef');
+            }
+        }
+        else {                        # positional
+            if $<quant> eq '?' {      #  optional (required is default)
+                $past.viviself('Undef');
+            }
+        }
+    }
+    make $past;
+}
+##.sub 'parameter' :method
+##    .param pmc match
+##    .param pmc key
+##    .local pmc past, sigil
+##    past = match['param_var']
+##    past = past.'get_scalar'()
+##    sigil = match['param_var';'sigil']
+##    if key != 'slurp' goto not_slurp
+##    if sigil != '@' goto not_slurpy_array
+##    past.'slurpy'(1)
+##  not_slurpy_array:
+##    if sigil != '%' goto not_slurpy_hash
+##    past.'slurpy'(1)
+##  not_slurpy_hash:
+##    if sigil != '%' goto not_slurp
+##    past.'named'(1)
+##    goto make_past
+##  not_slurp:
+##    $S0 = match['named']
+##    if $S0 != ':' goto not_named
+##    $S0 = match['param_var';'ident']
+##    past.'named'($S0)
+##    $S0 = match['quant']
+##    if $S0 == '!' goto not_named
+##    past.'viviself'('Undef')
+##  not_named:
+##    $S0 = match['quant']
+##    if $S0 != '?' goto make_past
+##    past.'viviself'('Undef')
+##  make_past:
+##    match.'result_object'(past)
+##.end
+
+
+method param_var($/) {
+    make PAST::Var.new(:name(~$/),
+                       :scope('parameter'),
+                       :node($/) );
+}
+##.sub 'param_var' :method
+##    .param pmc match
+##    $S0 = match
+##    $P0 = get_hll_global ['PAST'], 'Var'
+##    $P1 = $P0.'new'('name'=>$S0, 'scope'=>'parameter', 'node'=>match)
+##    match.'result_object'($P1)
+##.end
+
+
+#### Terms and expressions ####
+
+method term($/) {
+    my $past := $($<noun>);
+    for $<postfix> {
+        my $term := $past;
+        $past := $($_);
+        #print("term()");
+        $past.unshift($term);
+    }
+    make $past;
+}
+##.sub 'term' :method
+##    .param pmc match
+##    .param pmc key
+##    .local pmc past
+##    $P0 = match['noun']
+##    past = $P0.'get_scalar'()
+##    $P1 = match['postfix']
+##    if null $P1 goto end
+##    .local pmc iter, term
+##    iter = new 'Iterator', $P1
+##  iter_loop:
+##    unless iter goto end
+##    $P2 = shift iter
+##    term = past
+##    past = $P2.'get_scalar'()
+##    past.'unshift'(term)
+##    goto iter_loop
+##  end:
+##    match.'result_object'(past)
+##.end
+
+
+method postfix($/, $key) {
+    make $($/{$key});
+}
+##.sub 'postfix' :method
+##    .param pmc match
+##    .param string key
+##    $P0 = match[key]
+##    $P1 = $P0.'get_scalar'()
+##    match.'result_object'($P1)
+##.end
+
+
+method methodop($/, $key) {
+    my $past := $($<arglist>);
+    $past.name(~$<ident>);
+    $past.pasttype('callmethod');
+    $past.node($/);
+    make $past;
+}
+##.sub 'methodop' :method
+##    .param pmc match
+##    .param string key
+##    .local pmc past
+##    $P0 = match['arglist']
+##    past = $P0.'get_scalar'()
+##    $S0 = match['ident']
+##    past.'name'($S0)
+##    past.'pasttype'('callmethod')
+##    past.'node'(match)
+##    match.'result_object'(past)
+##.end
+
+
+method postcircumfix($/, $key) {
+    if $key eq '( )' {
+        my $past := $($<arglist>);
+        $past.pasttype('call');
+        $past.node($/);
+        make $past;
+    }
+    elsif $key eq '< >' {
+        my $value := PAST::Val.new( :value( $($<string_literal>) ) );
+        make PAST::Var.new( $value,
+                            :scope('keyed'),
+                            :vivibase('Hash'),
+                            :viviself('Undef'),
+                            :node( $/ ) );
+    }
+    else {
+        my $vivibase; ## := ($key eq '{ }') ? 'Hash' : 'ResizablePMCArray';
+        if $key eq '{ }' {
+            $vivibase := 'Hash';
+        }
+        else {
+            $vivibase := 'ResizablePMCArray';
+        }
+        make PAST::Var.new( $($<EXPR>),
+                            :scope('keyed'),
+                            :vivibase($vivibase),
+                            :viviself('Undef'),
+                            :node($/) );
+    }
+}
+##.sub 'postcircumfix' :method
+##    .param pmc match
+##    .param string key
+##    .local pmc past
+##    if key == '( )' goto subcall
+##    if key == '< >' goto keyed_const
+##  keyed_var:
+##    .local string vivibase
+##    vivibase = 'ResizablePMCArray'
+##    if key != '{ }' goto keyed_array
+##    vivibase = 'Hash'
+##  keyed_array:
+##    $P0 = get_hll_global ['PAST'], 'Var'
+##    $P1 = match['EXPR']
+##    $P2 = $P1.'get_scalar'()
+##    $P3 = $P0.'new'( $P2, 'scope'=>'keyed', 'vivibase'=>vivibase, 
'viviself'=>'Undef', 'node'=>match )
+##    match.'result_object'($P3)
+##    .return ()
+##  subcall:
+##    $P0 = match['arglist']
+##    past = $P0.'get_scalar'()
+##    past.'pasttype'('call')
+##    past.'node'(match)
+##    match.'result_object'(past)
+##    .return ()
+##  keyed_const:
+##    $P0 = get_hll_global ['PAST'], 'Val'
+##    $P1 = match['string_literal']
+##    $P2 = $P1.'get_scalar'()
+##    .local pmc value
+##    value = $P0.'new'( 'value' => $P2, 'node'=> $P1 )
+##    $P0 = get_hll_global ['PAST'], 'Var'
+##    $P1 = $P0.'new'( value, 'scope'=>'keyed', 'vivibase'=>'Hash', 
'viviself'=>'Undef', 'node'=>match)
+##    match.'result_object'($P1)
+##.end
+
+
+method circumfix($/, $key) {
+    my $expr := $($<EXPR>[0]);
+    if $key eq '@( )' {
+        make PAST::Op.new( $expr,
+                           :name('get_array'),
+                           :pasttype('callmethod'),
+                           :node($/) );
+    }
+    if $key eq '$( )' {
+        make PAST::Op.new( $expr,
+                           :name('get_scalar'),
+                           :pasttype('callmethod'),
+                           :node($/) );
+    }
+    make $expr;
+}
+##.sub 'circumfix' :method
+##    .param pmc match
+##    .param string key
+##    .local pmc past
+##    $P0 = match['EXPR']
+##    unless null $P0 goto have_expr
+##    $P1 = match
+##    goto get_past
+##  have_expr:
+##    $P1 = $P0[0]
+##  get_past:
+##    $P1 = $P1.'get_scalar'()
+##    $P0 = get_hll_global ['PAST'], 'Op'
+##    if key == '@( )' goto list_context
+##    if key == '$( )' goto scalar_context
+##  parenthetical:
+##    match.'result_object'($P1)
+##    .return ()
+##  list_context:
+##    past = $P0.'new'($P1, 'name' => 'get_array',  'pasttype'=>'callmethod', 
'node'=>match)
+##    match.'result_object'(past)
+##    .return ()
+##  scalar_context:
+##    past = $P0.'new'($P1, 'name' => 'get_scalar', 'pasttype'=>'callmethod', 
'node'=>match)
+##    match.'result_object'(past)
+##.end
+
+#sub callarg($arg) {
+#        if $arg.returns() eq 'Pair' {
+#            $arg[1].named($arg[0]);
+#            $arg := $arg[1];
+#        }
+#        return $arg;
+#}
+
+method arglist($/) {
+    my $past := PAST::Op.new( :node($/) );
+    if ($<EXPR>) {
+        my $expr := $($<EXPR>[0]);
+        if ($expr.name() eq 'infix:,') {
+            for @($expr) {
+                if $_.returns() eq 'Pair' {
+                    $_[1].named($_[0]);
+                    $_ := $_[1];
+                }
+                $past.push( $_ );
+            }
+        }
+        else {
+            if $expr.returns() eq 'Pair' {
+                $expr[1].named($expr[0]);
+                $expr := $expr[1];
+            }
+            $past.push( $expr );
+        }
+    }
+    make $past;
+}
+##.sub 'arglist' :method
+##    .param pmc match
+##    .local pmc past
+##    $P0 = get_hll_global ['PAST'], 'Op'
+##    past = $P0.'new'( 'node'=>match )
+##    $P1 = match['EXPR']
+##    if null $P1 goto end
+##    .local pmc expr, iter
+##    $P2 = $P1[0]
+##    expr = $P2.'get_scalar'()
+##    $S0 = expr.'name'()
+##    if $S0 != 'infix:,' goto one_arg
+##  comma_arg:
+##    .local pmc iter
+##    iter = expr.'iterator'()
+##  iter_loop:
+##    unless iter goto end
+##    $P0 = shift iter
+##    $P0 = 'callarg'($P0)
+##    past.'push'($P0)
+##    goto iter_loop
+##  one_arg:
+##    $P0 = 'callarg'(expr)
+##    past.'push'($P0)
+##  end:
+##    match.'result_object'(past)
+##.end
+
+
+##.sub 'callarg'
+##    .param pmc arg
+##    $S0 = arg.'returns'()
+##    unless $S0 == 'Pair' goto end
+##    $P0 = arg[0]
+##    $P1 = arg[1]
+##    $P1.'named'($P0)
+##    arg = $P1
+##  end:
+##    .return (arg)
+##.end
+
+
+method noun($/, $key) {
+    make $($/{$key});
+}
+##.sub 'noun' :method
+##    .param pmc match
+##    .param pmc key
+##    $P0 = match[key]
+##    $P1 = $P0.'get_scalar'()
+##    match.'result_object'($P1)
+##.end
+
+
+method colonpair($/) {
+    make PAST::Op.new( PAST::Val.new( :value(~$<ident>),
+                                      :node($<ident>)),
+                       $($<EXPR>),
+                       :name('infix:=>'),
+                       :returns('Pair'),
+                       :node($/)
+                     );
+}
+##.sub 'colonpair' :method
+##    .param pmc match
+##    $S0 = match['ident']
+##    $P0 = match['ident']
+##    $P9 = get_hll_global ['PAST'], 'Val'
+##    $P1 = $P9.'new'('value'=>$S0, 'node'=>$P0)
+##    $P2 = match['EXPR']
+##    $P2 = $P2.'get_scalar'()
+##    $P9 = get_hll_global ['PAST'], 'Op'
+##    $P3 = $P9.'new'($P1, $P2, 'name'=>'infix:=>', 'returns'=>'Pair', 
'node'=>match)
+##    match.'result_object'($P3)
+##.end
+
+
+method package_declarator($/, $key) {
+    my $past := $($/{$key});
+    $past.namespace($<name><ident>);
+    $past.blocktype('declaration');
+    $past.pirflags(':init :load');
+    $past.lexical(0);
+
+    #if ($<sym> eq 'class') { ...code to make class... }
+
+    make $past;
+}
+#
+##.sub 'package_declarator' :method
+##    .param pmc match
+##    .param pmc key
+##    .local pmc past
+##    $P0 = match[key]
+##    past = $P0.'get_scalar'()
+##    $P1 = match['name']
+##    $P1 = $P1['ident']
+##    past.'namespace'($P1)
+##    past.'blocktype'('declaration')
+##    past.'pirflags'(':init :load')
+##    past.'lexical'(0)
+##    $S0 = match['sym']
+##    if $S0 != 'class' goto class_done
+##    .local string inline
+##    inline = <<'        INLINE'
+##        $P0 = get_hll_global 'Protomaker'
+##        $P1 = split '::', '%s'
+##        push_eh subclass_done
+##        $P2 = $P0.'new_subclass'('Protoobject', $P1)
+##        pop_eh
+##      subclass_done:
+##        INLINE
+##    $S0 = match['name']
+##    $I0 = index inline, '%s'
+##    substr inline, $I0, 2, $S0
+##    $P0 = get_hll_global ['PAST'], 'Op'
+##    $P1 = $P0.'new'('inline'=>inline, 'pasttype'=>'inline')
+##    $P2 = past[0]
+##    $P2.'push'($P1)
+##  class_done:
+##    match.'result_object'(past)
+##.end
+
+
+method scope_declarator($/) {
+     my $past := $($<variable>);
+     my $name := $past.name();
+     our $?BLOCK;
+     unless $?BLOCK.symbol($name) {
+         $past.isdecl(1);
+         #my $scope := ($<declarator> eq 'my') ? 'lexical' : 'package';
+         my $scope;
+         if $<declarator> eq 'my' {
+             $scope := 'lexical';
+         }
+         else {
+             $scope := 'package';
+         }
+         $?BLOCK.symbol($name, :scope($scope));
+     }
+     make $past;
+}
+##.sub 'scope_declarator' :method
+##    .param pmc match
+##    .local pmc past, block
+##    .local string name
+##    $P0 = match['variable']
+##    past = $P0.'get_scalar'()
+##    name = past.'name'()
+##    block = get_global '$?BLOCK'
+##    $P0 = block.'symbol'(name)
+##    if $P0 goto end
+##    past.'isdecl'(1)
+##    .local string scope
+##    scope = 'package'
+##    $S0 = match['declarator']
+##    if $S0 != 'my' goto have_scope
+##    scope = 'lexical'
+##  have_scope:
+##    block.'symbol'(name, 'scope'=>scope)
+##  end:
+##    match.'result_object'(past)
+##.end
+
+
+method variable($/, $key) {
+    if ($key eq '$< >') {
+        say("variable", ~$/[0]);
+        make PAST::Var.new(
+                 PAST::Var.new(:scope('lexical'), :name('$/')),
+                 PAST::Val.new(:value(~$/[0])),
+                 :scope('keyed'),
+                 :viviself('Undef') );
+    }
+    else {
+        make PAST::Var.new(:node($/), :name(~$/) );
+    }
+}
+##.sub 'variable' :method
+##    .param pmc match
+##    .param pmc key
+##    if key != '$< >' goto past_var
+##  past_match_keyed:
+##    $P0 = get_hll_global ['PAST'], 'Var'
+##    $P1 = $P0.'new'('scope'=>'lexical', 'name'=>'$/')
+##    $P2 = get_hll_global ['PAST'], 'Val'
+##    $S0 = match[0]
+##    $P3 = $P2.'new'('value'=>$S0)
+##    $P4 = $P0.'new'($P1, $P3, 'scope'=>'keyed', 'viviself'=>'Undef')
+##    match.'result_object'($P4)
+##    .return ()
+##  past_var:
+##    $S0 = match
+##    $S1 = match['sigil']
+##    $S2 = 'Undef'
+##    if $S1 != '%' goto past_sigil_is_array
+##    $S2 = 'Hash'
+##    goto past_sigil
+##  past_sigil_is_array:
+##    if $S1 != '@' goto past_sigil
+##    $S2 = 'ResizablePMCArray'
+##    goto past_sigil
+##  past_sigil:
+##    $P0 = get_hll_global ['PAST'], 'Var'
+##    $P1 = $P0.'new'('node'=>match, 'name'=>$S0, 'viviself'=>$S2)
+##    match.'result_object'($P1)
+##.end
+
+
+method value($/, $key) {
+    make $($/{$key});
+}
+###.sub 'value' :method
+###    .param pmc match
+###    .param pmc key
+###    $P0 = match[key]
+###    $P1 = $P0.'get_scalar'()
+###    match.'result_object'($P1)
+###.end
+
+
+method quote($/) {
+    make PAST::Val.new(:node($/), :value(~($<string_literal>)));
+}
+##.sub 'quote' :method
+##    .param pmc match
+##    .param pmc key             :optional
+##    .local string value
+##    $P0 = match['string_literal']
+##    value = $P0.'get_scalar'()
+##    $P0 = get_hll_global ['PAST'], 'Val'
+##    $P1 = $P0.'new'('node'=>match, 'value'=>value)
+##    match.'result_object'($P1)
+##.end
+
+
+
+## stolen from NQP
+method typename($/) {
+    my $ns := $<name><ident>;
+    my $shortname;
+    PIR q<    $P0 = find_lex '$ns'         >;
+    PIR q<    $P0 = clone $P0              >;
+    PIR q<    $P1 = pop $P0                >;
+    PIR q<    store_lex '$ns', $P0         >;
+    PIR q<    store_lex '$shortname', $P1  >;
+    make PAST::Var.new( :name($shortname),
+                        :namespace($ns),
+                        :scope('package'),
+                        :node($/)
+                      );
+}
+
+
+##.sub 'typename' :method
+##    .param pmc match
+##    .param pmc key
+##    .local pmc ns, name
+##    $P0 = match['name']
+##    $P0 = $P0['ident']
+##    ns = clone $P0
+##    name = pop ns
+##    $P0 = get_hll_global ['PAST'], 'Var'
+##    $P1 = $P0.'new'('node'=>match, 'scope'=>'package', 'name'=>name, 
'namespace'=>ns)
+##    match.'result_object'($P1)
+##.end
+
+
+method number($/, $key?) {
+    make PAST::Val.new(:node($/), :value(~$/), :returns('Integer'));
+}
+##.sub 'number' :method
+##    .param pmc match
+##    .param pmc key             :optional
+##    .local pmc past
+##    $I0 = match
+##    $P0 = get_hll_global ['PAST'], 'Val'
+##    past = $P0.'new'('node'=>match, 'value'=>$I0)
+##    match.'result_object'(past)
+##.end
+
+
+method subcall($/, $key?) {
+    my $past := $($<arglist>);
+    $past.name(~$<ident>);
+    $past.pasttype('call');
+    $past.node($/);
+    make $past;
+}
+##.sub 'subcall' :method
+##    .param pmc match
+##    .param pmc key             :optional
+##    .local pmc past
+##    $P0 = match['arglist']
+##    past = $P0.'get_scalar'()
+##    $S0 = match['ident']
+##    past.'name'($S0)
+##    past.'pasttype'('call')
+##    past.'node'(match)
+##    match.'result_object'(past)
+##.end
+
+
+#### Expressions and operators ####
+method EXPR($/, $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 EXPR($/, $key) {
+#    if ($key eq 'end') {
+#        make $($<expr>);
+#    }
+#    my $past := PAST::Op.new( :node($/),
+#                              :name($<type>),
+#                              :pasttype($<top><pasttype>),
+#                               :inline($<top><inline>),
+#                              :pirop($<top><pirop>),
+#                              :lvalue($<top><lvalue>)
+#                            );
+#    for @($/) {
+#        $past.push($($_));
+#    }
+#    make $past;
+#}
+##.sub 'EXPR' :method
+##    .param pmc match
+##    .param pmc key
+##    if key != 'end' goto expr_reduce
+##  expr_end:
+##    $P0 = match['expr']
+##    $P1 = $P0.'get_scalar'()
+##    match.'result_object'($P1)
+##    .return ()
+##  expr_reduce:
+##    .local pmc past
+##    .local string name, pirop, pasttype, inline, lvalue
+##    name = match['type']
+##    pirop = match['top';'pirop']
+##    pasttype = match['top'; 'pasttype']
+##    inline = match['top'; 'inline']
+##    lvalue = match['top'; 'lvalue']
+##    $P0 = get_hll_global ['PAST'], 'Op'
+##    past = $P0.'new'('node'=>match, 'name'=>name, 'pirop'=>pirop, 
'pasttype'=>pasttype, 'inline'=>inline, 'lvalue'=>lvalue)
+##    $P1 = match.'get_array'()
+##    if null $P1 goto iter_end
+##    .local pmc iter
+##    iter = new 'Iterator', $P1
+##  iter_loop:
+##    unless iter goto iter_end
+##    $P2 = shift iter
+##    $P2 = $P2.'get_scalar'()
+##    past.'push'($P2)
+##    goto iter_loop
+##  iter_end:
+##    match.'result_object'(past)
+##.end
+
+# Local Variables:
+#   mode: pir
+#   fill-column: 100
+# End:
+# vim: expandtab shiftwidth=4 ft=pir:

Reply via email to