Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Get term:name fixed up a bit.
  • Loading branch information
jnthn committed May 24, 2011
1 parent dff1ae8 commit 5360e04
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 27 deletions.
39 changes: 13 additions & 26 deletions src/Perl6/Actions.pm
Expand Up @@ -1863,39 +1863,26 @@ class Perl6::Actions is HLL::Actions {
}

method term:sym<name>($/) {
my $ns := Perl6::Grammar::parse_name(~$<longname>);
$ns := pir::clone__PP($ns);
my $name := $ns.pop;
my $var;
if is_lexical(~$<longname>) {
$var := PAST::Var.new( :name(~$<longname>), :scope('lexical') );
}
else {
$var := PAST::Var.new(
:name(~$name), :namespace($ns), :scope('package'),
:viviself(PAST::Op.new(
:pasttype('call'), :name('!FAIL'),
"Cannot find sub " ~ ~$<longname>
))
);
# If it's a call, ensure we have &.
my @name := Perl6::Grammar::parse_name(~$<longname>);
if $<args> {
my $final := @name[+@name - 1];
if pir::substr($final, 0, 1) ne '&' {
@name[+@name - 1] := '&' ~ $final;
}
}

# Build lookup, and if there's args call it.
my $var := $*ST.symbol_lookup(@name, $/);
my $past := $var;
if $<args> {
$past := capture_or_parcel($<args>.ast, ~$<longname>);
if $ns {
$past.unshift($var);
unless pir::substr($var.name, 0, 1) eq '&' {
$var.name('&' ~ $var.name);
}
}
else { $past.name('&' ~ $name); }
$past.unshift($var);
}
elsif $<arglist> {
$past := $<arglist>[0].ast;
$past.pasttype('callmethod');
$past.name('!select');
$past.unshift($var);
$/.CURSOR.panic("Parametric roles not yet implemented");
}

$past.node($/);
make $past;
}
Expand Down
2 changes: 1 addition & 1 deletion src/Perl6/Grammar.pm
Expand Up @@ -1400,7 +1400,7 @@ grammar Perl6::Grammar is HLL::Grammar {
[
|| <?{
my $longname := $<longname>.Str;
pir::substr($longname, 0, 2) eq '::' || $/.CURSOR.is_name($longname)
pir::substr($longname, 0, 2) eq '::' || $*ST.is_type(parse_name($longname))
}>
<.unsp>? [ <?before '['> '[' ~ ']' <arglist> ]?
|| <args>
Expand Down
75 changes: 75 additions & 0 deletions src/Perl6/SymbolTable.pm
Expand Up @@ -423,6 +423,81 @@ class Perl6::SymbolTable is HLL::Compiler::SerializationContextBuilder {
$result;
}

# Takes a name and compiles it to a lookup for the symbol.
method symbol_lookup(@name, $/) {
# Catch empty names and die helpfully.
if +@name == 0 { $/.CURSOR.panic("Cannot compile empty name"); }

# If it's a single item, then go hunting for it through the
# block stack.
if +@name == 1 {
my $i := +@!BLOCKS;
while $i > 0 {
$i := $i - 1;
my %sym := @!BLOCKS[$i].symbol(@name[0]);
if +%sym {
return PAST::Var.new( :name(@name[0]), :scope(%sym<scope>) );
}
}
}

# The final lookup will always be just a keyed access to a
# symbol table.
my $final_name := @name.pop();
my $lookup := PAST::Var.new( :scope('keyed'), ~$final_name);

# If there's no explicit qualification, then look it up in the
# current package, and fall back to looking in GLOBAL.
if +@name == 0 {
$lookup.unshift(PAST::Op.new(
:pirop('get_who PP'),
PAST::Var.new( :name('$?PACKAGE'), :scope('lexical') )
));
$lookup.viviself(PAST::Var.new(
:scope('keyed'),
PAST::Op.new(
:pirop('get_who PP'),
PAST::Var.new( :name('GLOBAL'), :namespace([]), :scope('package') )
),
~$final_name
));
}

# Otherwise, see if the first part of the name is lexically
# known. If not, it's in GLOBAL. Also, if first part is GLOBAL
# then strip it off.
else {
my $path := self.is_lexical(@name[0]) ??
PAST::Var.new( :name(@name.shift()), :scope('lexical') ) !!
PAST::Var.new( :name('GLOBAL'), :namespace([]), :scope('package') );
if @name[0] eq 'GLOBAL' {
@name.shift();
}
for @name {
$path := PAST::Op.new(
:pirop('nqp_get_package_through_who PPs'),
$path, ~$_);
}
$lookup.unshift(PAST::Op.new(:pirop('get_who PP'), $path));
}

return $lookup;
}

# Checks if the given name is known anywhere in the lexpad
# and with lexical scope.
method is_lexical($name) {
my $i := +@!BLOCKS;
while $i > 0 {
$i := $i - 1;
my %sym := @!BLOCKS[$i].symbol($name);
if +%sym {
return %sym<scope> eq 'lexical';
}
}
0;
}

# XXX TODO
method is_attr_alias($name) {
0
Expand Down

0 comments on commit 5360e04

Please sign in to comment.