Skip to content

Commit 5942262

Browse files
committed
Fix BEGIN blocks, they get outer lexicals and can return a value. Add a test.
1 parent afa84b8 commit 5942262

File tree

2 files changed

+46
-14
lines changed

2 files changed

+46
-14
lines changed

src/NQP/World.nqp

Lines changed: 35 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -458,36 +458,57 @@ class NQP::World is HLL::World {
458458
QAST::Stmts.new(),
459459
$past
460460
);
461+
462+
$past<DYN_COMP_WRAPPER> := 1;
461463
my %seen;
464+
my $mu := try { self.find_symbol(['NQPMu']) };
462465
my $i := +@!BLOCKS;
463466
while $i > 0 {
464467
$i := $i - 1;
465468
my %symbols := @!BLOCKS[$i].symtable();
466469
for %symbols {
467-
if !%seen{$_.key} && nqp::existskey($_.value, 'value') {
470+
unless %seen{$_.key} {
471+
# Add symbol.
472+
my %sym := $_.value;
473+
my $value := nqp::existskey(%sym, 'value') ?? %sym<value> !! $mu;
468474
try {
469-
$wrapper[0].push(QAST::Op.new(
470-
:op('bind'),
471-
QAST::Var.new( :name($_.key), :scope('lexical'), :isdecl('var') ),
472-
QAST::WVal.new( :value(($_.value)<value>) )
475+
if nqp::isnull(nqp::getobjsc($value)) {
476+
self.add_object($value);
477+
}
478+
CATCH {
479+
$value := $mu;
480+
}
481+
}
482+
if !nqp::isnull($value) {
483+
$wrapper[0].push(QAST::Var.new(
484+
:name($_.key), :scope('lexical'),
485+
:decl('static'),
486+
:value($value),
473487
));
474-
};
475-
%seen{$_.key} := 1;
488+
}
489+
$wrapper.symbol($_.key, :scope('lexical'));
490+
476491
}
492+
%seen{$_.key} := 1;
477493
}
478494
}
479-
495+
480496
# Compile and run it.
481497
my $code := self.create_code($wrapper, 'BEGIN block', 0);
482498
my $old_global := nqp::getcurhllsym('GLOBAL');
483-
nqp::bindcurhllsym('GLOBAL', $*GLOBALish);
484-
$code();
499+
nqp::bindcurhllsym('GLOBAL', $*GLOBALish); # cargo culted
500+
my $r := $code();
485501
nqp::bindcurhllsym('GLOBAL', $old_global);
486502

487-
# Need any nested blocks inside the BEGIN block to make it into the
488-
# output code.
489-
$wrapper.shift();
490-
return $wrapper;
503+
504+
if nqp::isint($r) {
505+
QAST::IVal.new(:value($r));
506+
} elsif nqp::isstr($r) {
507+
QAST::SVal.new(:value($r));
508+
} else {
509+
self.add_object($r);
510+
QAST::WVal.new(:value($r))
511+
}
491512
}
492513

493514
# Adds libraries that NQP code depends on.

t/nqp/69-begin.t

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
plan(5);
2+
ok(nqp::istype(&say,NQPRoutine),"checking builtins, &say is a NQPRoutine");
3+
ok(nqp::istype(&ok,NQPRoutine),"checking builtins, &ok is a NQPRoutine");
4+
sub foo() {
5+
}
6+
ok(nqp::istype(&foo,NQPRoutine),"named sub is NQPRoutine");
7+
ok(nqp::istype(sub() {},NQPRoutine),"anoymous sub is NQPRoutine");
8+
my $foo := sub bar() {
9+
};
10+
ok(nqp::istype($foo,NQPRoutine),"binding a named sub to a value results in a NQPRoutine");
11+

0 commit comments

Comments
 (0)