diff --git a/src/NQP/Actions.pm b/src/NQP/Actions.pm index 055fec2..e977163 100644 --- a/src/NQP/Actions.pm +++ b/src/NQP/Actions.pm @@ -207,7 +207,15 @@ method variable($/) { $past.unshift( PAST::Var.new( :name('$/') ) ); } else { - $past := PAST::Var.new( :name(~$/) ); + my @name := NQP::Compiler.parse_name(~$/); + $past := PAST::Var.new( :name(~@name.pop) ); + if (@name) { + if @name[0] eq 'GLOBAL' { @name.shift; } + $past.namespace(@name); + $past.scope('package'); + $past.viviself( sigiltype( $ ) ); + $past.lvalue(1); + } if $[0] eq '*' { $past.scope('contextual'); $past.viviself( PAST::Op.new( 'Contextual ' ~ ~$/ ~ ' not found', diff --git a/src/NQP/Compiler.pir b/src/NQP/Compiler.pir index cae8b9a..11aa7f4 100644 --- a/src/NQP/Compiler.pir +++ b/src/NQP/Compiler.pir @@ -21,7 +21,7 @@ NQP::Compiler - NQP compiler .sub '' :anon :load :init .local pmc p6meta, nqpproto p6meta = get_hll_global 'P6metaclass' - nqpproto = p6meta.'new_class'('Regex::P6Grammar::Compiler', 'parent'=>'HLL::Compiler') + nqpproto = p6meta.'new_class'('NQP::Compiler', 'parent'=>'HLL::Compiler') nqpproto.'language'('NQP-rx') $P0 = get_hll_global ['NQP'], 'Grammar' nqpproto.'parsegrammar'($P0) diff --git a/src/NQP/Grammar.pm b/src/NQP/Grammar.pm index 84707a1..823d4e1 100644 --- a/src/NQP/Grammar.pm +++ b/src/NQP/Grammar.pm @@ -204,7 +204,7 @@ token colonpair { } token variable { - | ? + | ? | | $=['$'] $=[<[/_!]>] } diff --git a/src/cheats/hll-compiler.pir b/src/cheats/hll-compiler.pir index 792b29f..85789de 100644 --- a/src/cheats/hll-compiler.pir +++ b/src/cheats/hll-compiler.pir @@ -75,3 +75,39 @@ .return ($S0) .end + +.sub 'parse_name' :method + .param string name + + # split name on :: + .local pmc ns + ns = split '::', name + + # move any leading sigil to the last item + .local string sigil + $S0 = ns[0] + sigil = substr $S0, 0, 1 + $I0 = index '$@%&', sigil + if $I0 < 0 goto sigil_done + substr $S0, 0, 1, '' + ns[0] = $S0 + $S0 = ns[-1] + $S0 = concat sigil, $S0 + ns[-1] = $S0 + sigil_done: + + # remove any empty items from the list + .local pmc ns_it + ns_it = iter ns + ns = new ['ResizablePMCArray'] + ns_loop: + unless ns_it goto ns_done + $S0 = shift ns_it + unless $S0 > '' goto ns_loop + push ns, $S0 + goto ns_loop + ns_done: + + # return the result + .return (ns) +.end diff --git a/t/nqp/43-package-var.t b/t/nqp/43-package-var.t new file mode 100644 index 0000000..6ce5281 --- /dev/null +++ b/t/nqp/43-package-var.t @@ -0,0 +1,24 @@ +#! nqp.pbc + +# Accessing package variables directly + +plan(3); + +our $var; + +$GLOBAL::var := 1; +$ABC::def := 2; +@XYZ::ghi[0] := 3; + +ok( $var == 1, '$GLOBAL::var works'); + + +module ABC { + our $def; + ok( $def == 2, '$ABC::def works'); +} + +module XYZ { + our @ghi; + ok( @ghi[0] == 3, '@XYZ::ghi works'); +}