[perl #61088] [PATCH] show result of expressions in HLLCompiler based interactive REPLs

[email protected] ("gabriele renzi")
Newsgroups perl.perl6.internals
Message-ID <[email protected]>
# New Ticket Created by  "gabriele renzi" 
# Please include the string:  [perl #61088]
# in the subject line of all future correspondence about this issue. 
# <URL: http://rt.perl.org/rt3/Ticket/Display.html?id=61088 >


the current HLLCompiler infrastructure seems to be an incomplete REPL,
since it only does Read-Eval-Loop.
This patch adds a simple Print step and a new attribute
commandline_result_prompt similar to commandline_prompt, defaulting to
"=> ".
It also changes the default commandline_prompt to " >> " to make the
two vertically aligned.

A better approach may be splitting the functionality of the
interactive() method into calls to multiple overrideable methods
(read, print) to allow further
customization from users of the class.

the difference is easy to show, with rakudo:
>> 1
=> 1
>> 1+3
=> 4
>> say "hello"
hello
=> 1
>> 1.WHAT
=> Int
>> 1.HOW
=> get_string() not implemented in class 'P6metaclass'
current instr.: 'parrot;PCT;HLLCompiler;interactive' pc 1072
(src/PCT/HLLCompiler.pir:592)
called from Sub 'parrot;PCT;HLLCompiler;command_line' pc 1470
(src/PCT/HLLCompiler.pir:793)
called from Sub 'parrot;Perl6;Compiler;main' pc 16749 (perl6.pir:166)

vs
> 1
> 1+3
> say "hello"
hello
> 1.WHAT
> 1.HOW
>

I did not install an exception handler for missing failure in the
internal say() call cause it feels this should not happen anyway.

OTOH other exceptions are correctly handled as usual
>> say miao
Could not find non-existent sub miao
>> say $miao
Scope not found for PAST::Var '$miao'
>>


Furthermore, notice that if the result of the operation is null
nothing is printed (python-like behaviour) so for example the default
language shell will have

>> say 1;
1
>> say "hello";
"hello"
>>

All parrot and rakudo tests seem to pass, which means that probably
there are no tests for this functionality at all.

The patch respects the previous behaviour of special casing the PIR
target so that it does not print anything else.
repl3.patch (application/octet-stream, 2.9 KB)
Index: compilers/pct/src/PCT/HLLCompiler.pir
===================================================================
--- compilers/pct/src/PCT/HLLCompiler.pir	(revision 33557)
+++ compilers/pct/src/PCT/HLLCompiler.pir	(working copy)
@@ -15,7 +15,7 @@
     load_bytecode 'P6object.pbc'
     load_bytecode 'Parrot/Exception.pbc'
     $P0 = new 'P6metaclass'
-    $S0 = '@stages $parsegrammar $parseactions $astgrammar $commandline_banner $commandline_prompt @cmdoptions $usage $version'
+    $S0 = '@stages $parsegrammar $parseactions $astgrammar $commandline_banner $commandline_prompt $commandline_result_prompt @cmdoptions $usage $version'
     $P0.'new_class'('PCT::HLLCompiler', 'attr'=>$S0)
 .end
 
@@ -143,6 +143,13 @@
 The prompt is displayed in interactive mode at each point where
 the compiler is ready for code to be compiled and executed.
 
+=item commandline_result_prompt([string value])
+
+Set the command-line prompt for result of this computation to C<value>.
+The prompt is displayed in interactive mode after each point where
+the code is inserted showing the result of the computation.
+
+
 =cut
 
 .sub 'stages' :method
@@ -181,6 +188,11 @@
     .tailcall self.'attr'('$commandline_prompt', value, has_value)
 .end
 
+.sub 'commandline_result_prompt' :method
+    .param string value        :optional
+    .param int has_value       :opt_flag
+    .tailcall self.'attr'('$commandline_result_prompt', value, has_value)
+.end
 =item removestage(string stagename)
 
 Delete a stage from the compilation process queue.
@@ -530,6 +542,15 @@
     $P0 = self.'commandline_banner'()
     printerr $P0
 
+    ## set result prompt once 
+    .local string result_prompt
+    result_prompt = '=> '
+    $P0 = self.'commandline_result_prompt'()
+    $I0 = defined $P0
+    unless $I0 goto has_result_prompt
+    result_prompt = $P0
+
+  has_result_prompt:
     .local pmc stdin
     .local int has_readline
     stdin = getstdin
@@ -538,21 +559,23 @@
     if encoding == 'fixed_8' goto interactive_loop
     unless encoding goto interactive_loop
     push stdin, encoding
+
   interactive_loop:
     .local pmc code
     unless stdin goto interactive_end
-
     .local string prompt
-    prompt = '> '
+    prompt = '>> '
     $P0 = self.'commandline_prompt'()
     $I0 = defined $P0
     unless $I0 goto have_prompt
     prompt = $P0
+
   have_prompt:
 
     ##  display a prompt ourselves if readline isn't present
     if has_readline != -1 goto interactive_read
     printerr prompt
+
   interactive_read:
     code = stdin.'readline'(prompt)
     if null code goto interactive_end
@@ -562,9 +585,13 @@
     $P0 = self.'eval'(code, adverbs :flat :named)
     pop_eh
     if null $P0 goto interactive_loop
-    unless target goto interactive_loop
+    unless target goto interactive_print
     if target == 'pir' goto target_pir
     '_dumper'($P0, target)
+  interactive_print:
+    print result_prompt
+    print $P0
+    print "\n"
     goto interactive_loop
   target_pir:
     say $P0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.