@@ -5,24 +5,23 @@ extern crate env_logger;
55extern crate log;
66
77use clap:: { App , AppSettings , Arg , ArgMatches } ;
8- use rustpython_compiler:: { compile, error:: CompileError , error:: CompileErrorType } ;
9- use rustpython_parser:: error:: ParseErrorType ;
8+ use rustpython_compiler:: compile;
109use rustpython_vm:: {
1110 import, match_class,
1211 obj:: { objint:: PyInt , objtuple:: PyTuple , objtype} ,
1312 print_exception,
14- pyobject:: { ItemProtocol , PyObjectRef , PyResult } ,
13+ pyobject:: { ItemProtocol , PyResult } ,
1514 scope:: Scope ,
1615 util, PySettings , VirtualMachine ,
1716} ;
18- use std:: convert:: TryInto ;
1917
18+ use std:: convert:: TryInto ;
2019use std:: env;
2120use std:: path:: PathBuf ;
2221use std:: process;
2322use std:: str:: FromStr ;
2423
25- mod shell_helper ;
24+ mod shell ;
2625
2726fn main ( ) {
2827 #[ cfg( feature = "flame-it" ) ]
@@ -367,7 +366,7 @@ fn run_rustpython(vm: &VirtualMachine, matches: &ArgMatches) -> PyResult<()> {
367366 } else if let Some ( filename) = matches. value_of ( "script" ) {
368367 run_script ( & vm, scope, filename) ?
369368 } else {
370- run_shell ( & vm, scope) ?;
369+ shell :: run_shell ( & vm, scope) ?;
371370 }
372371
373372 Ok ( ( ) )
@@ -459,225 +458,3 @@ fn test_run_script() {
459458 let r = run_script ( & vm, vm. new_scope_with_builtins ( ) , "tests/snippets/dir_main" ) ;
460459 assert ! ( r. is_ok( ) ) ;
461460}
462-
463- enum ShellExecResult {
464- Ok ,
465- PyErr ( PyObjectRef ) ,
466- Continue ,
467- }
468-
469- fn shell_exec ( vm : & VirtualMachine , source : & str , scope : Scope ) -> ShellExecResult {
470- match vm. compile ( source, compile:: Mode :: Single , "<stdin>" . to_string ( ) ) {
471- Ok ( code) => {
472- match vm. run_code_obj ( code, scope. clone ( ) ) {
473- Ok ( value) => {
474- // Save non-None values as "_"
475- if !vm. is_none ( & value) {
476- let key = "_" ;
477- scope. globals . set_item ( key, value, vm) . unwrap ( ) ;
478- }
479- ShellExecResult :: Ok
480- }
481- Err ( err) => ShellExecResult :: PyErr ( err) ,
482- }
483- }
484- Err ( CompileError {
485- error : CompileErrorType :: Parse ( ParseErrorType :: EOF ) ,
486- ..
487- } ) => ShellExecResult :: Continue ,
488- Err ( err) => ShellExecResult :: PyErr ( vm. new_syntax_error ( & err) ) ,
489- }
490- }
491-
492- #[ cfg( not( target_os = "wasi" ) ) ]
493- fn run_shell ( vm : & VirtualMachine , scope : Scope ) -> PyResult < ( ) > {
494- use rustyline:: { error:: ReadlineError , CompletionType , Config , Editor } ;
495-
496- println ! (
497- "Welcome to the magnificent Rust Python {} interpreter \u{1f631} \u{1f596} " ,
498- crate_version!( )
499- ) ;
500-
501- // Read a single line:
502- let mut repl = Editor :: with_config (
503- Config :: builder ( )
504- . completion_type ( CompletionType :: List )
505- . build ( ) ,
506- ) ;
507- repl. set_helper ( Some ( shell_helper:: ShellHelper :: new ( vm, scope. clone ( ) ) ) ) ;
508- let mut full_input = String :: new ( ) ;
509-
510- // Retrieve a `history_path_str` dependent on the OS
511- let repl_history_path = match dirs:: config_dir ( ) {
512- Some ( mut path) => {
513- path. push ( "rustpython" ) ;
514- path. push ( "repl_history.txt" ) ;
515- path
516- }
517- None => ".repl_history.txt" . into ( ) ,
518- } ;
519-
520- if !repl_history_path. exists ( ) {
521- if let Some ( parent) = repl_history_path. parent ( ) {
522- std:: fs:: create_dir_all ( parent) . unwrap ( ) ;
523- }
524- }
525-
526- if repl. load_history ( & repl_history_path) . is_err ( ) {
527- println ! ( "No previous history." ) ;
528- }
529-
530- let mut continuing = false ;
531-
532- loop {
533- let prompt_name = if continuing { "ps2" } else { "ps1" } ;
534- let prompt = vm
535- . get_attribute ( vm. sys_module . clone ( ) , prompt_name)
536- . and_then ( |prompt| vm. to_str ( & prompt) ) ;
537- let prompt = match prompt {
538- Ok ( ref s) => s. as_str ( ) ,
539- Err ( _) => "" ,
540- } ;
541- let result = match repl. readline ( prompt) {
542- Ok ( line) => {
543- debug ! ( "You entered {:?}" , line) ;
544-
545- repl. add_history_entry ( line. trim_end ( ) ) ;
546-
547- let stop_continuing = line. is_empty ( ) ;
548-
549- if full_input. is_empty ( ) {
550- full_input = line;
551- } else {
552- full_input. push_str ( & line) ;
553- }
554- full_input. push_str ( "\n " ) ;
555-
556- if continuing {
557- if stop_continuing {
558- continuing = false ;
559- } else {
560- continue ;
561- }
562- }
563-
564- match shell_exec ( vm, & full_input, scope. clone ( ) ) {
565- ShellExecResult :: Ok => {
566- full_input. clear ( ) ;
567- Ok ( ( ) )
568- }
569- ShellExecResult :: Continue => {
570- continuing = true ;
571- Ok ( ( ) )
572- }
573- ShellExecResult :: PyErr ( err) => {
574- full_input. clear ( ) ;
575- Err ( err)
576- }
577- }
578- }
579- Err ( ReadlineError :: Interrupted ) => {
580- continuing = false ;
581- full_input. clear ( ) ;
582- let keyboard_interrupt = vm
583- . new_empty_exception ( vm. ctx . exceptions . keyboard_interrupt . clone ( ) )
584- . unwrap ( ) ;
585- Err ( keyboard_interrupt)
586- }
587- Err ( ReadlineError :: Eof ) => {
588- break ;
589- }
590- Err ( err) => {
591- eprintln ! ( "Readline error: {:?}" , err) ;
592- break ;
593- }
594- } ;
595-
596- if let Err ( exc) = result {
597- if objtype:: isinstance ( & exc, & vm. ctx . exceptions . system_exit ) {
598- repl. save_history ( & repl_history_path) . unwrap ( ) ;
599- return Err ( exc) ;
600- }
601- print_exception ( vm, & exc) ;
602- }
603- }
604- repl. save_history ( & repl_history_path) . unwrap ( ) ;
605-
606- Ok ( ( ) )
607- }
608-
609- #[ cfg( target_os = "wasi" ) ]
610- fn run_shell ( vm : & VirtualMachine , scope : Scope ) -> PyResult < ( ) > {
611- use std:: io:: prelude:: * ;
612- use std:: io:: { self , BufRead } ;
613-
614- println ! (
615- "Welcome to the magnificent Rust Python {} interpreter \u{1f631} \u{1f596} " ,
616- crate_version!( )
617- ) ;
618-
619- // Read a single line:
620- let mut input = String :: new ( ) ;
621- let mut continuing = false ;
622-
623- loop {
624- let prompt_name = if continuing { "ps2" } else { "ps1" } ;
625- let prompt = vm
626- . get_attribute ( vm. sys_module . clone ( ) , prompt_name)
627- . and_then ( |prompt| vm. to_str ( & prompt) ) ;
628- let prompt = match prompt {
629- Ok ( ref s) => s. as_str ( ) ,
630- Err ( _) => "" ,
631- } ;
632- print ! ( "{}" , prompt) ;
633- io:: stdout ( ) . flush ( ) . ok ( ) . expect ( "Could not flush stdout" ) ;
634-
635- let stdin = io:: stdin ( ) ;
636-
637- let result = match stdin. lock ( ) . lines ( ) . next ( ) . unwrap ( ) {
638- Ok ( line) => {
639- debug ! ( "You entered {:?}" , line) ;
640- let stop_continuing = line. is_empty ( ) ;
641-
642- if input. is_empty ( ) {
643- input = line;
644- } else {
645- input. push_str ( & line) ;
646- }
647- input. push_str ( "\n " ) ;
648-
649- if continuing {
650- if stop_continuing {
651- continuing = false ;
652- } else {
653- continue ;
654- }
655- }
656-
657- match shell_exec ( vm, & input, scope. clone ( ) ) {
658- ShellExecResult :: Ok => {
659- input. clear ( ) ;
660- Ok ( ( ) )
661- }
662- ShellExecResult :: Continue => {
663- continuing = true ;
664- Ok ( ( ) )
665- }
666- ShellExecResult :: PyErr ( err) => {
667- input. clear ( ) ;
668- Err ( err)
669- }
670- }
671- }
672- Err ( err) => {
673- eprintln ! ( "Readline error: {:?}" , err) ;
674- break ;
675- }
676- } ;
677-
678- if let Err ( exc) = result {
679- print_exception ( vm, & exc) ;
680- }
681- }
682- Ok ( ( ) )
683- }
0 commit comments