@@ -38,6 +38,13 @@ impl Compiler {
3838 )
3939 }
4040
41+ fn block_is_void ( expr : & Expr ) -> bool {
42+ match expr {
43+ Expr :: Block ( exprs) => exprs. last ( ) . map ( |e| Self :: is_void ( & e. node ) ) . unwrap_or ( true ) ,
44+ _ => false ,
45+ }
46+ }
47+
4148 // chunk shit
4249
4350 fn emit ( & mut self , instruction : Instruction , span : SimpleSpan ) {
@@ -348,8 +355,12 @@ impl Compiler {
348355
349356 Expr :: And ( a, b) => {
350357 self . compile_expr ( * a. clone ( ) ) ?;
358+
359+ let skip = self . emit_jump ( Instruction :: JumpIfFalse ( 0 ) , span) ;
360+ self . emit ( Instruction :: Pop , span) ;
361+
351362 self . compile_expr ( * b. clone ( ) ) ?;
352- self . emit ( Instruction :: And , span ) ;
363+ self . patch_jump ( skip ) ;
353364 }
354365
355366 Expr :: Or ( a, b) => {
@@ -396,6 +407,11 @@ impl Compiler {
396407 self . continue_targets . push ( start) ;
397408
398409 self . compile_expr ( * body. clone ( ) ) ?;
410+
411+ if !Self :: block_is_void ( & body. node ) {
412+ self . emit ( Instruction :: Pop , span) ;
413+ }
414+
399415 self . emit ( Instruction :: Jump ( start) , span) ;
400416
401417 let breaks = self . break_patches . pop ( ) . unwrap ( ) ;
@@ -415,6 +431,11 @@ impl Compiler {
415431 let exit = self . emit_jump ( Instruction :: JumpIfFalse ( 0 ) , span) ;
416432
417433 self . compile_expr ( * body. clone ( ) ) ?;
434+
435+ if !Self :: block_is_void ( & body. node ) {
436+ self . emit ( Instruction :: Pop , span) ;
437+ }
438+
418439 self . emit ( Instruction :: Jump ( start) , span) ;
419440
420441 let breaks = self . break_patches . pop ( ) . unwrap ( ) ;
@@ -469,6 +490,11 @@ impl Compiler {
469490
470491 // body
471492 self . compile_expr ( * body. clone ( ) ) ?;
493+
494+ if !Self :: block_is_void ( & body. node ) {
495+ self . emit ( Instruction :: Pop , span) ;
496+ }
497+
472498 self . emit ( Instruction :: Jump ( start) , span) ;
473499
474500 self . patch_jump ( exit) ;
0 commit comments