From eaa4deb2738645dfe7c1228027227c5d16117314 Mon Sep 17 00:00:00 2001 From: pmichaud Date: Wed, 26 May 2010 00:53:18 -0500 Subject: [PATCH] Add a more lexically-aware interactive REPL. Still some tweaks wanted. --- build/PARROT_REVISION | 2 +- src/HLL/Compiler.pm | 22 ++++++++++++++++++++-- src/NQP/Actions.pm | 4 ++++ src/cheats/hll-compiler.pir | 21 +++++++++++++++++++++ 4 files changed, 46 insertions(+), 3 deletions(-) diff --git a/build/PARROT_REVISION b/build/PARROT_REVISION index c4f60fa..567756d 100644 --- a/build/PARROT_REVISION +++ b/build/PARROT_REVISION @@ -1 +1 @@ -46979 +47014 diff --git a/src/HLL/Compiler.pm b/src/HLL/Compiler.pm index 8c9ef2f..665e122 100644 --- a/src/HLL/Compiler.pm +++ b/src/HLL/Compiler.pm @@ -108,17 +108,26 @@ class HLL::Compiler is PCT::HLLCompiler { # Set the current position of stdout for autoprinting control my $*AUTOPRINTPOS := pir::tell__IP(pir::getstdout__P()); + our $interactive_ctx; + our %interactive_pad; + my $*CTXSAVE := self; + my $*MAIN_CTX; if $code { $code := $code ~ "\n"; my $output; { - $output := self.eval($code, |%adverbs); + $output := self.eval($code, :outer_ctx($interactive_ctx), |%adverbs); CATCH { pir::print(~$! ~ "\n"); next; } }; + if pir::defined($*MAIN_CTX) { + for $*MAIN_CTX.lexpad_full() { + %interactive_pad{$_.key} := $_.value; + } + } next if pir::isnull($output); if !$target { @@ -140,7 +149,7 @@ class HLL::Compiler is PCT::HLLCompiler { && %adverbs eq '' { my $outer_ctx := %adverbs; if pir::defined($outer_ctx) { - $output[0].set_outer(pir::getattribute__PPs($outer_ctx, 'current_sub')); + $output[0].set_outer_ctx($outer_ctx); } pir::trace(%adverbs); @@ -150,4 +159,13 @@ class HLL::Compiler is PCT::HLLCompiler { $output; } + + method ctxsave() { + $*MAIN_CTX := + Q:PIR { + $P0 = getinterp + %r = $P0['context';1] + }; + $*CTXSAVE := 0; + } } diff --git a/src/NQP/Actions.pm b/src/NQP/Actions.pm index 5ad6095..8e9b3a9 100644 --- a/src/NQP/Actions.pm +++ b/src/NQP/Actions.pm @@ -50,6 +50,10 @@ method comp_unit($/) { my $mainline := $.ast; my $unit := @BLOCK.shift; + # If our caller wants to know the mainline ctx, provide it here. + # (CTXSAVE is inherited from HLL::Actions.) + $unit.push( self.CTXSAVE() ); + # We force a return here, because we have other # :load/:init blocks to execute that we don't want # to include as part of the mainline. diff --git a/src/cheats/hll-compiler.pir b/src/cheats/hll-compiler.pir index 6a35c0c..569453a 100644 --- a/src/cheats/hll-compiler.pir +++ b/src/cheats/hll-compiler.pir @@ -103,3 +103,24 @@ # return the result .return (ns) .end + + +# This sub serves as a cumulative "outer context" for code +# executed in HLL::Compiler's interactive REPL. It's invoked +# exactly once upon load/init to obtain a context, and its +# default LexPad is replaced with a Hash that we can use to +# cumulatively store outer context information. Both the +# context and hash are then made available via package +# variables. +.namespace [] +.sub '&interactive_outer' :lex :init :load + .local pmc ctx, pad + $P0 = getinterp + ctx = $P0['context'] + set_global ['HLL';'Compiler'], '$interactive_ctx', ctx + pad = getattribute ctx, 'lex_pad' + $P1 = new ['Hash'] + copy pad, $P1 + set_global ['HLL';'Compiler'], '%interactive_pad', pad +.end +