1- //extern crate rustpython_parser;
21#[ macro_use]
32extern crate clap;
43extern crate env_logger;
@@ -9,16 +8,21 @@ extern crate rustpython_vm;
98extern crate rustyline;
109
1110use clap:: { App , Arg } ;
12- use rustpython_parser:: parser;
13- use rustpython_vm:: obj:: objstr;
14- use rustpython_vm:: print_exception;
15- use rustpython_vm:: pyobject:: { AttributeProtocol , PyObjectRef , PyResult } ;
16- use rustpython_vm:: VirtualMachine ;
17- use rustpython_vm:: { compile, import} ;
18- use rustyline:: error:: ReadlineError ;
19- use rustyline:: Editor ;
20- use std:: path:: Path ;
21- use std:: path:: PathBuf ;
11+ use rustpython_parser:: error:: ParseError ;
12+ use rustpython_vm:: {
13+ compile,
14+ error:: CompileError ,
15+ import,
16+ obj:: objstr,
17+ print_exception,
18+ pyobject:: { AttributeProtocol , PyObjectRef , PyResult } ,
19+ util, VirtualMachine ,
20+ } ;
21+ use rustyline:: { error:: ReadlineError , Editor } ;
22+ use std:: {
23+ error:: Error ,
24+ path:: { Path , PathBuf } ,
25+ } ;
2226
2327fn main ( ) {
2428 env_logger:: init ( ) ;
@@ -69,7 +73,16 @@ fn main() {
6973}
7074
7175fn _run_string ( vm : & mut VirtualMachine , source : & str , source_path : String ) -> PyResult {
72- let code_obj = compile:: compile ( vm, source, & compile:: Mode :: Exec , source_path) ?;
76+ let code_obj = compile:: compile (
77+ source,
78+ & compile:: Mode :: Exec ,
79+ source_path,
80+ vm. ctx . code_type ( ) ,
81+ )
82+ . map_err ( |err| {
83+ let syntax_error = vm. context ( ) . exceptions . syntax_error . clone ( ) ;
84+ vm. new_exception ( syntax_error, err. description ( ) . to_string ( ) )
85+ } ) ?;
7386 // trace!("Code object: {:?}", code_obj.borrow());
7487 let builtins = vm. get_builtin_scope ( ) ;
7588 let vars = vm. context ( ) . new_scope ( Some ( builtins) ) ; // Keep track of local variables
@@ -100,35 +113,31 @@ fn run_module(vm: &mut VirtualMachine, module: &str) -> PyResult {
100113fn run_script ( vm : & mut VirtualMachine , script_file : & str ) -> PyResult {
101114 debug ! ( "Running file {}" , script_file) ;
102115 // Parse an ast from it:
103- let filepath = Path :: new ( script_file) ;
104- match parser :: read_file ( filepath ) {
105- Ok ( source) => _run_string ( vm, & source, filepath . to_str ( ) . unwrap ( ) . to_string ( ) ) ,
106- Err ( msg ) => {
107- error ! ( "Parsing went horribly wrong : {}" , msg ) ;
116+ let file_path = Path :: new ( script_file) ;
117+ match util :: read_file ( file_path ) {
118+ Ok ( source) => _run_string ( vm, & source, file_path . to_str ( ) . unwrap ( ) . to_string ( ) ) ,
119+ Err ( err ) => {
120+ error ! ( "Failed reading file : {:? }" , err . kind ( ) ) ;
108121 std:: process:: exit ( 1 ) ;
109122 }
110123 }
111124}
112125
113126fn shell_exec ( vm : & mut VirtualMachine , source : & str , scope : PyObjectRef ) -> bool {
114- match compile:: compile ( vm , source, & compile:: Mode :: Single , "<stdin>" . to_string ( ) ) {
127+ match compile:: compile ( source, & compile:: Mode :: Single , "<stdin>" . to_string ( ) , vm . ctx . code_type ( ) ) {
115128 Ok ( code) => {
116129 if let Err ( err) = vm. run_code_obj ( code, scope) {
117130 print_exception ( vm, & err) ;
118131 }
119132 }
133+ // Don't inject syntax errors for line continuation
134+ Err ( CompileError :: Parse ( ParseError :: EOF ( _) ) ) => {
135+ return false ;
136+ }
120137 Err ( err) => {
121- // Enum rather than special string here.
122- let name = vm. new_str ( "msg" . to_string ( ) ) ;
123- let msg = match vm. get_attribute ( err. clone ( ) , name) {
124- Ok ( value) => objstr:: get_value ( & value) ,
125- Err ( _) => panic ! ( "Expected msg attribute on exception object!" ) ,
126- } ;
127- if msg == "Unexpected end of input." {
128- return false ;
129- } else {
130- print_exception ( vm, & err) ;
131- }
138+ let syntax_error = vm. context ( ) . exceptions . syntax_error . clone ( ) ;
139+ let exc = vm. new_exception ( syntax_error, format ! ( "{}" , err) ) ;
140+ print_exception ( vm, & exc) ;
132141 }
133142 } ;
134143 true
0 commit comments