@@ -228,13 +228,13 @@ def tokens_append(j, token):
228
228
229
229
if show_asm in ("both" , "before" ):
230
230
print ("\n # ---- disassembly:" )
231
- self . insts = bytecode .disassemble_bytes (
231
+ bytecode .disassemble_bytes (
232
232
co .co_code ,
233
233
varnames = co .co_varnames ,
234
234
names = co .co_names ,
235
235
constants = co .co_consts ,
236
236
cells = bytecode ._cell_names ,
237
- linestarts = bytecode ._linestarts ,
237
+ line_starts = bytecode ._linestarts ,
238
238
asm_format = "extended" ,
239
239
filename = co .co_filename ,
240
240
show_source = True ,
@@ -481,12 +481,17 @@ def tokens_append(j, token):
481
481
next_opname = self .insts [i + 1 ].opname
482
482
483
483
# 'Continue's include jumps to loops that are not
484
- # and the end of a block which follow with POP_BLOCK and COME_FROM_LOOP.
485
- # If the JUMP_ABSOLUTE is to a FOR_ITER and it is followed by another JUMP_FORWARD
486
- # then we'll take it as a "continue".
487
- is_continue = (
488
- self .insts [self .offset2inst_index [target ]].opname == "FOR_ITER"
489
- and self .insts [i + 1 ].opname == "JUMP_FORWARD"
484
+ # and the end of a block which follow with
485
+ # POP_BLOCK and COME_FROM_LOOP. If the
486
+ # JUMP_ABSOLUTE is to a FOR_ITER, and it is
487
+ # followed by another JUMP_FORWARD then we'll take
488
+ # it as a "continue".
489
+ next_inst = self .insts [i + 1 ]
490
+ is_continue = self .insts [
491
+ self .offset2inst_index [target ]
492
+ ].opname == "FOR_ITER" and next_inst .opname in (
493
+ "JUMP_FORWARD" ,
494
+ "JUMP_ABSOLUTE" ,
490
495
)
491
496
492
497
if self .version < (3 , 8 ) and (
@@ -501,21 +506,65 @@ def tokens_append(j, token):
501
506
):
502
507
opname = "CONTINUE"
503
508
else :
509
+ # "continue" versus "break_loop" dectction is more complicated
510
+ # because "continue" to an outer loop is really a "break loop"
504
511
opname = "JUMP_BACK"
512
+
505
513
# FIXME: this is a hack to catch stuff like:
506
514
# if x: continue
507
515
# the "continue" is not on a new line.
508
- # There are other situations where we don't catch
509
- # CONTINUE as well.
510
- if tokens [- 1 ].kind == "JUMP_BACK" and tokens [- 1 ].attr <= argval :
516
+ #
517
+ # Another situation is where we have
518
+ # for method in methods:
519
+ # for B in method:
520
+ # if c:
521
+ # return
522
+ # break # A "continue" but not the innermost one
523
+ if tokens [- 1 ].kind == "JUMP_LOOP" and tokens [- 1 ].attr <= argval :
511
524
if tokens [- 2 ].kind == "BREAK_LOOP" :
512
525
del tokens [- 1 ]
526
+ j -= 1
513
527
else :
514
- # intern is used because we are changing the *previous* token
515
- tokens [- 1 ].kind = sys .intern ("CONTINUE" )
516
- if last_op_was_break and opname == "CONTINUE" :
517
- last_op_was_break = False
518
- continue
528
+ # "intern" is used because we are
529
+ # changing the *previous* token. A
530
+ # POP_TOP suggests a "break" rather
531
+ # than a "continue"?
532
+ if tokens [- 2 ] == "POP_TOP" and (
533
+ is_continue and next_inst .argval != tokens [- 1 ].attr
534
+ ):
535
+ tokens [- 1 ].kind = sys .intern ("BREAK_LOOP" )
536
+ else :
537
+ tokens [- 1 ].kind = sys .intern ("CONTINUE" )
538
+ last_continue = tokens [- 1 ]
539
+ pass
540
+ pass
541
+ pass
542
+ # elif (
543
+ # last_continue is not None
544
+ # and tokens[-1].kind == "JUMP_LOOP"
545
+ # and last_continue.attr <= tokens[-1].attr
546
+ # and last_continue.offset > tokens[-1].attr
547
+ # ):
548
+ # # Handle mis-characterized "CONTINUE"
549
+ # # We have a situation like:
550
+ # # loop ... for or while)
551
+ # # loop
552
+ # # if ...: # code below starts here
553
+ # # break # not continue
554
+ # #
555
+ # # POP_JUMP_IF_FALSE_LOOP # to outer loop
556
+ # # JUMP_LOOP # to inner loop
557
+ # # ...
558
+ # # JUMP_LOOP # to outer loop
559
+ # tokens[-2].kind = sys.intern("BREAK_LOOP")
560
+ # pass
561
+
562
+ # if last_op_was_break and opname == "CONTINUE":
563
+ # last_op_was_break = False
564
+ # continue
565
+ pass
566
+ else :
567
+ opname = "JUMP_FORWARD"
519
568
520
569
elif inst .offset in self .load_asserts :
521
570
opname = "LOAD_ASSERT"
@@ -538,9 +587,10 @@ def tokens_append(j, token):
538
587
)
539
588
pass
540
589
541
- if show_asm in ("both" , "after" ):
590
+ if show_asm in ("both" , "after" ) and self . version < ( 3 , 8 ) :
542
591
print ("\n # ---- tokenization:" )
543
- for t in tokens :
592
+ # FIXME: t.format() is changing tokens!
593
+ for t in tokens .copy ():
544
594
print (t .format (line_prefix = "" ))
545
595
print ()
546
596
return tokens , customize
0 commit comments