Skip to content

Commit

Permalink
Make lexicals visible inside of eval. This depends on some recent Par…
Browse files Browse the repository at this point in the history
…rot changes, so bump up required version number. There are two parts to this: letting the parser know what lexicals are declared in the outer scope so it doesn't claim about them being undeclared, and then doing a .set_outer so the lexicals can be found at runtime.
  • Loading branch information
jnthn committed Mar 14, 2009
1 parent 41267fd commit e9aca5f
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 1 deletion.
2 changes: 1 addition & 1 deletion build/PARROT_REVISION
@@ -1 +1 @@
37317
37414
35 changes: 35 additions & 0 deletions src/builtins/control.pir
Expand Up @@ -304,6 +304,31 @@ on error.
'die'("Parameter type check failed on call to 'eval'.")
type_ok:

# We want to make the lexicals known to the Perl 6 compiler. (One day
# PCT maybe will provide a way to tell any language about these.)
.local pmc blocks, block_info, interp, sub
interp = new 'ParrotInterpreter'
$P0 = get_hll_global ['PAST'], 'Block'
block_info = $P0.'new'()
sub = interp["sub"; 1]
lex_loop:
if null sub goto lex_loop_end
$P0 = sub.'get_lexinfo'()
$P0 = inspect $P0, 'symbols'
$P0 = iter $P0
symbols_loop:
unless $P0 goto symbols_loop_end
$S0 = shift $P0
block_info.'symbol'($S0, 'scope'=>'lexical')
goto symbols_loop
symbols_loop_end:
sub = sub.'get_outer'()
goto lex_loop
lex_loop_end:
blocks = get_hll_global ['Perl6';'Grammar';'Actions'], '@?BLOCK'
block_info['eval'] = 1
blocks.'unshift'(block_info)

.local pmc compiler, invokable
.local pmc res, exception
unless have_lang goto no_lang
Expand All @@ -324,6 +349,15 @@ on error.
got_lang:
invokable = compiler.'compile'(code)

# Clear lexical info we added.
blocks.'shift'()

# Set lexical scope.
$P0 = interp["sub"; 1]
$P1 = invokable[0]
$P1.'set_outer'($P0)

# Invoke.
res = invokable()
exception = new 'Failure'
goto done
Expand All @@ -333,6 +367,7 @@ on error.

done:
pop_eh

# Propagate exception to caller
$P0 = getinterp
$P0 = $P0['lexpad';1]
Expand Down
7 changes: 7 additions & 0 deletions src/parser/actions.pm
Expand Up @@ -29,10 +29,17 @@ method TOP($/) {
# Create the unit's startup block, unless it's suppressed.
our $?SUPPRESS_MAIN;
my $main;
our @?BLOCK;
if $?SUPPRESS_MAIN {
$past.push(PAST::Stmts.new());
$main := $past;
}
elsif +@?BLOCK && @?BLOCK[0]<eval> == 1 {
$past.blocktype('immediate');
$past.lexical(1);
@?BLOCK[0].push($past);
$main := @?BLOCK[0];
}
else {
$main := PAST::Block.new( :pirflags(':main') );
$main.loadinit().push(
Expand Down

0 comments on commit e9aca5f

Please sign in to comment.