@@ -100,19 +100,6 @@ impl CompileContext {
100100 }
101101}
102102
103- /// A helper function for the shared code of the different compile functions
104- fn with_compiler (
105- source_path : String ,
106- opts : CompileOpts ,
107- f : impl FnOnce ( & mut Compiler ) -> CompileResult < ( ) > ,
108- ) -> CompileResult < CodeObject > {
109- let mut compiler = Compiler :: new ( opts, source_path, "<module>" . to_owned ( ) ) ;
110- f ( & mut compiler) ?;
111- let code = compiler. pop_code_object ( ) ;
112- trace ! ( "Compilation completed: {:?}" , code) ;
113- Ok ( code)
114- }
115-
116103/// Compile an ast::Mod produced from rustpython_parser::parser::parse()
117104pub fn compile_top (
118105 ast : & ast:: Mod ,
@@ -127,16 +114,24 @@ pub fn compile_top(
127114 }
128115}
129116
130- macro_rules! compile_impl {
131- ( $ast: expr, $source_path: expr, $opts: expr, $st: ident, $compile: ident) => { {
132- let symbol_table = match $st( $ast) {
133- Ok ( x) => x,
134- Err ( e) => return Err ( e. into_compile_error( $source_path) ) ,
135- } ;
136- with_compiler( $source_path, $opts, |compiler| {
137- compiler. $compile( $ast, symbol_table)
138- } )
139- } } ;
117+ /// A helper function for the shared code of the different compile functions
118+ fn compile_impl < Ast : ?Sized > (
119+ ast : & Ast ,
120+ source_path : String ,
121+ opts : CompileOpts ,
122+ make_symbol_table : impl FnOnce ( & Ast ) -> Result < SymbolTable , symboltable:: SymbolTableError > ,
123+ compile : impl FnOnce ( & mut Compiler , & Ast , SymbolTable ) -> CompileResult < ( ) > ,
124+ ) -> CompileResult < CodeObject > {
125+ let symbol_table = match make_symbol_table ( ast) {
126+ Ok ( x) => x,
127+ Err ( e) => return Err ( e. into_compile_error ( source_path) ) ,
128+ } ;
129+
130+ let mut compiler = Compiler :: new ( opts, source_path, "<module>" . to_owned ( ) ) ;
131+ compile ( & mut compiler, ast, symbol_table) ?;
132+ let code = compiler. pop_code_object ( ) ;
133+ trace ! ( "Compilation completed: {:?}" , code) ;
134+ Ok ( code)
140135}
141136
142137/// Compile a standard Python program to bytecode
@@ -145,7 +140,13 @@ pub fn compile_program(
145140 source_path : String ,
146141 opts : CompileOpts ,
147142) -> CompileResult < CodeObject > {
148- compile_impl ! ( ast, source_path, opts, make_symbol_table, compile_program)
143+ compile_impl (
144+ ast,
145+ source_path,
146+ opts,
147+ make_symbol_table,
148+ Compiler :: compile_program,
149+ )
149150}
150151
151152/// Compile a Python program to bytecode for the context of a REPL
@@ -154,12 +155,12 @@ pub fn compile_program_single(
154155 source_path : String ,
155156 opts : CompileOpts ,
156157) -> CompileResult < CodeObject > {
157- compile_impl ! (
158+ compile_impl (
158159 ast,
159160 source_path,
160161 opts,
161162 make_symbol_table,
162- compile_program_single
163+ Compiler :: compile_program_single,
163164 )
164165}
165166
@@ -168,7 +169,13 @@ pub fn compile_expression(
168169 source_path : String ,
169170 opts : CompileOpts ,
170171) -> CompileResult < CodeObject > {
171- compile_impl ! ( ast, source_path, opts, make_symbol_table_expr, compile_eval)
172+ compile_impl (
173+ ast,
174+ source_path,
175+ opts,
176+ make_symbol_table_expr,
177+ Compiler :: compile_eval,
178+ )
172179}
173180
174181impl Compiler {
@@ -309,7 +316,7 @@ impl Compiler {
309316 let size_before = self . code_stack . len ( ) ;
310317 self . symbol_table_stack . push ( symbol_table) ;
311318
312- let ( statements , doc ) = get_doc ( body) ;
319+ let ( doc , statements ) = split_doc ( body) ;
313320 if let Some ( value) = doc {
314321 self . emit_constant ( ConstantData :: Str { value } ) ;
315322 let doc = self . name ( "__doc__" ) ;
@@ -337,31 +344,30 @@ impl Compiler {
337344 ) -> CompileResult < ( ) > {
338345 self . symbol_table_stack . push ( symbol_table) ;
339346
340- let mut emitted_return = false ;
341-
342- for ( i, statement) in body. iter ( ) . enumerate ( ) {
343- let is_last = i == body. len ( ) - 1 ;
347+ let ( last, body) = if let Some ( splited) = body. split_last ( ) {
348+ splited
349+ } else {
350+ return Ok ( ( ) ) ;
351+ } ;
344352
353+ for statement in body {
345354 if let ast:: StmtKind :: Expr { value } = & statement. node {
346355 self . compile_expression ( value) ?;
347-
348- if is_last {
349- self . emit ( Instruction :: Duplicate ) ;
350- self . emit ( Instruction :: PrintExpr ) ;
351- self . emit ( Instruction :: ReturnValue ) ;
352- emitted_return = true ;
353- } else {
354- self . emit ( Instruction :: PrintExpr ) ;
355- }
356+ self . emit ( Instruction :: PrintExpr ) ;
356357 } else {
357358 self . compile_statement ( statement) ?;
358359 }
359360 }
360361
361- if !emitted_return {
362+ if let ast:: StmtKind :: Expr { value } = & last. node {
363+ self . compile_expression ( value) ?;
364+ self . emit ( Instruction :: Duplicate ) ;
365+ self . emit ( Instruction :: PrintExpr ) ;
366+ } else {
367+ self . compile_statement ( last) ?;
362368 self . emit_constant ( ConstantData :: None ) ;
363- self . emit ( Instruction :: ReturnValue ) ;
364369 }
370+ self . emit ( Instruction :: ReturnValue ) ;
365371
366372 Ok ( ( ) )
367373 }
@@ -1046,7 +1052,7 @@ impl Compiler {
10461052 let qualified_name = self . qualified_path . join ( "." ) ;
10471053 self . push_qualified_path ( "<locals>" ) ;
10481054
1049- let ( body , doc_str ) = get_doc ( body) ;
1055+ let ( doc_str , body ) = split_doc ( body) ;
10501056
10511057 self . compile_statements ( body) ?;
10521058
@@ -1165,6 +1171,7 @@ impl Compiler {
11651171 true
11661172 }
11671173
1174+ // Python/compile.c find_ann
11681175 fn find_ann ( & self , body : & [ ast:: Stmt ] ) -> bool {
11691176 use ast:: StmtKind :: * ;
11701177
@@ -1216,7 +1223,7 @@ impl Compiler {
12161223
12171224 self . push_output ( bytecode:: CodeFlags :: empty ( ) , 0 , 0 , 0 , name. to_owned ( ) ) ;
12181225
1219- let ( new_body , doc_str ) = get_doc ( body) ;
1226+ let ( doc_str , body ) = split_doc ( body) ;
12201227
12211228 let dunder_name = self . name ( "__name__" ) ;
12221229 self . emit ( Instruction :: LoadGlobal ( dunder_name) ) ;
@@ -1234,7 +1241,7 @@ impl Compiler {
12341241 if self . find_ann ( body) {
12351242 self . emit ( Instruction :: SetupAnnotation ) ;
12361243 }
1237- self . compile_statements ( new_body ) ?;
1244+ self . compile_statements ( body ) ?;
12381245
12391246 let classcell_idx = self
12401247 . code_stack
@@ -2566,15 +2573,15 @@ impl Compiler {
25662573 }
25672574}
25682575
2569- fn get_doc ( body : & [ ast:: Stmt ] ) -> ( & [ ast:: Stmt ] , Option < String > ) {
2576+ fn split_doc ( body : & [ ast:: Stmt ] ) -> ( Option < String > , & [ ast:: Stmt ] ) {
25702577 if let Some ( ( val, body_rest) ) = body. split_first ( ) {
25712578 if let ast:: StmtKind :: Expr { value } = & val. node {
25722579 if let Some ( doc) = try_get_constant_string ( std:: slice:: from_ref ( value) ) {
2573- return ( body_rest , Some ( doc) ) ;
2580+ return ( Some ( doc) , body_rest ) ;
25742581 }
25752582 }
25762583 }
2577- ( body , None )
2584+ ( None , body )
25782585}
25792586
25802587fn try_get_constant_string ( values : & [ ast:: Expr ] ) -> Option < String > {
0 commit comments