Front page | perl.cvs.parrot |
Postings from January 2009
[svn:parrot] r34877 - branches/rvar/languages/perl6/src/parser
From:
pmichaud
Date:
January 3, 2009 06:14
Subject:
[svn:parrot] r34877 - branches/rvar/languages/perl6/src/parser
Message ID:
20090103141411.D470CCB9FA@x12.develooper.com
Author: pmichaud
Date: Sat Jan 3 06:14:11 2009
New Revision: 34877
Modified:
branches/rvar/languages/perl6/src/parser/actions.pm
Log:
[rakudo]: Clean up var node handling in actions.pm a bit.
Modified: branches/rvar/languages/perl6/src/parser/actions.pm
==============================================================================
--- branches/rvar/languages/perl6/src/parser/actions.pm (original)
+++ branches/rvar/languages/perl6/src/parser/actions.pm Sat Jan 3 06:14:11 2009
@@ -1530,49 +1530,35 @@
}
method variable($/, $key) {
- my $past;
+ my $var;
our @?BLOCK;
my $?BLOCK := @?BLOCK[0];
if $key eq 'desigilname' {
- my $sigil := ~$<sigil>;
- my $twigil := ~$<twigil>[0];
- my @identifier := Perl6::Compiler.parse_name( $<desigilname> );
- my $name := ~@identifier.pop();
- my $varname := $sigil ~ $name;
- $past := PAST::Var.new( :name($varname), :node($/) );
-
- ## if namespace qualified or has a '*' twigil, it's a package var
- if @identifier || $twigil eq '*' {
- $past.namespace(@identifier);
- $past.scope('package');
- $past.viviself( container_itype($sigil) );
- }
+ my $sigil := ~$<sigil>;
+ if $sigil eq '&' { $sigil := ''; }
+ my $twigil := ~$<twigil>[0];
+ my @ns := Perl6::Compiler.parse_name( $<desigilname> );
+ my $name := ~@ns.pop();
+ my $varname := $sigil ~ $twigil ~ $name;
- if $varname eq '@_' || $varname eq '%_' {
- unless $?BLOCK.symbol($varname) {
- $?BLOCK.symbol( $varname, :scope('lexical') );
- my $param := PAST::Var.new( :name($varname),
- :scope('parameter'),
- :slurpy(1) );
- if $sigil eq '%' { $param.named(1); }
- $?BLOCK[0].unshift($param);
- }
- }
-
- if $sigil eq '&' {
- $sigil := '';
- $varname := $name;
- $past.name($varname);
- $past.scope('package');
+ # If no twigil, but varname is 'attribute' in outer scope,
+ # it's really a private attribute and needs a '!' twigil
+ if !$twigil {
my $sym := outer_symbol($varname);
- if $sym && $sym<scope> { $past.scope( $sym<scope> ); }
+ if $sym && $sym<scope> eq 'attribute' {
+ $twigil := '!';
+ $varname := $sigil ~ $twigil ~ $name;
+ };
}
- ## if twigil is ^ or :, it's a placeholder var
+ # If twigil is ^ or :, it's a placeholder var. Create the
+ # parameter for the block if one doesn't already exist.
if $twigil eq '^' || $twigil eq ':' {
if $?BLOCK<signature> {
$/.panic("Cannot use placeholder var in block with signature.");
}
+ $twigil := '';
+ $varname := $sigil ~ $name;
unless $?BLOCK.symbol($varname) {
$?BLOCK.symbol( $varname, :scope('lexical') );
$?BLOCK.arity( +$?BLOCK.arity() + 1 );
@@ -1580,7 +1566,7 @@
if $twigil eq ':' { $param.named( $name ); }
my $block := $?BLOCK[0];
my $i := +@($block);
- while $i > 0 && $block[$i-1]<name> gt $varname {
+ while $i > 0 && $block[$i-1].name() gt $varname {
$block[$i] := $block[$i-1];
$i--;
}
@@ -1588,38 +1574,56 @@
}
}
- ## if no twigil, but variable is 'attribute' in an outer scope,
- ## it's really a private attribute
- if !$twigil {
+ $var := PAST::Var.new( :name($varname), :node($/) );
+ if $twigil { $var<twigil> := $twigil; }
+
+ # If namespace qualified or has a '*' twigil, it's a package var.
+ if @ns || $twigil eq '*' {
+ $var.namespace(@ns);
+ $var.scope('package');
+ $var.viviself( container_itype($sigil) );
+ }
+
+ ## @_ and %_ add a slurpy param to the block
+ if $varname eq '@_' || $varname eq '%_' {
+ unless $?BLOCK.symbol($varname) {
+ $?BLOCK.symbol( $varname, :scope('lexical') );
+ my $param := PAST::Var.new( :name($varname),
+ :scope('parameter'),
+ :slurpy(1) );
+ if $sigil eq '%' { $param.named(1); }
+ $?BLOCK[0].unshift($param);
+ }
+ }
+
+ # Until PCT has 'name' scope, we handle lexical/package lookup here.
+ if $<sigil> eq '&' {
+ $var.scope('package');
my $sym := outer_symbol($varname);
- if $sym && $sym<scope> eq 'attribute' { $twigil := '!' };
+ if $sym && $sym<scope> { $var.scope( $sym<scope> ); }
}
- ## handle ! and . twigil as attribute lookup...
- our @?IN_DECL;
+ # ! and . twigils may need 'self' for attribute lookup ...
if $twigil eq '!' || $twigil eq '.' {
- $varname := $sigil ~ $twigil ~ $name;
- $past.name($varname);
- $past.scope('attribute');
- $past.unshift( PAST::Var.new( :name('self'), :scope('lexical') ) );
+ $var.unshift( PAST::Var.new( :name('self'), :scope('lexical') ) );
}
- ## ...but return . twigil as a method call, saving the
- ## PAST::Var node in $past <vardecl>where it can be easily
- ## retrieved by <variable_declarator> if we're called from there.
+ # ...but return . twigil as a method call, saving the
+ # PAST::Var node in $var<vardecl> where it can be easily
+ # retrieved by <variable_declarator> if we're called from there.
if $twigil eq '.' {
- my $var := $past;
- $past := PAST::Op.new( :node($/), :pasttype('callmethod'),
+ my $vardecl := $var;
+ $var := PAST::Op.new( :node($/), :pasttype('callmethod'),
:name($name),
PAST::Var.new( :name('self'), :scope('lexical') )
);
- $past<vardecl> := $var;
+ $var<vardecl> := $vardecl;
}
}
elsif $key eq 'special_variable' {
- $past := $( $<special_variable> );
+ $var := $( $<special_variable> );
}
- make $past;
+ make $var;
}
-
[svn:parrot] r34877 - branches/rvar/languages/perl6/src/parser
by pmichaud