Skip to content

Commit 565ccb8

Browse files
committed
Separate assignment in expression into multiple statements
1 parent 905ed3f commit 565ccb8

File tree

2 files changed

+174
-29
lines changed

2 files changed

+174
-29
lines changed

java2python/lib/sourcetypes.py

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,10 @@ def __init__(self, parent=None, name=None):
106106
self.type = None
107107
self.variables = set()
108108

109+
self.postIncDecInExprFixed = False
110+
self.postIncDecVars = []
111+
self.postIncDecCount= 0
112+
109113
def __str__(self):
110114
""" str(obj) -> source code defined in obj
111115
@@ -160,6 +164,18 @@ def addSource(self, value):
160164
"""
161165
self.lines.append(value)
162166

167+
def addSourceBefore(self, value, stat=None):
168+
""" add source code to the end of this block, before the last line
169+
170+
@param value string, instance of Source (or subclass), or two-tuple
171+
@return None
172+
"""
173+
if len(self.lines) > 0:
174+
idx = -2 if stat == None else self.lines.index(stat)
175+
self.lines.insert(idx, value)
176+
else:
177+
self.lines.append(value)
178+
163179
def addVariable(self, name, force=False):
164180
""" add variable name to set for tracking
165181
@@ -324,6 +340,17 @@ def newStatement(self, name):
324340
self.addSource(s)
325341
return s
326342

343+
def newStatementBefore(self, name, stat=None):
344+
""" creates a new Statement as a child of this block before the last
345+
346+
@param name name of statement
347+
@param stat add statement before stat
348+
@return Statement instance
349+
"""
350+
s = Statement(parent=self, name=name)
351+
self.addSourceBefore(s, stat)
352+
return s
353+
327354
def formatExpression(self, expr):
328355
""" format an expression set by the tree walker
329356
@@ -406,6 +433,53 @@ def I(self, indent):
406433
"""
407434
return (' ' * self.config.last('indent', 4)) * indent
408435

436+
def fixAssignInExpr(self, needFix, expr, left):
437+
if not needFix: return expr
438+
if self.name == 'if':
439+
self.parent.addSourceBefore(expr, self)
440+
elif self.name == 'while':
441+
self.addSource(expr)
442+
elif isinstance(self, Method):
443+
self.addSource(expr)
444+
return left
445+
446+
def fixPostIncDecInExpr(self, needFix, expr, left, op):
447+
if not needFix: return expr
448+
if self.name == 'if':
449+
avar = "_%s0" % left[1]
450+
self.postIncDecVars.append((avar, left, op))
451+
self.postIncDecInExprFixed = True
452+
return '%s', avar
453+
else:
454+
self.postIncDecVars.append((left, op))
455+
self.postIncDecInExprFixed = True
456+
return '%s', left
457+
458+
def fixPostIncDecInExprAfter(self, expr):
459+
if not self.postIncDecInExprFixed: return expr
460+
if self.name == 'if':
461+
for var in self.postIncDecVars:
462+
self.parent.addSourceBefore((var[0] + ' = %s', var[1]), self)
463+
for var in self.postIncDecVars:
464+
self.parent.addSourceBefore(('%s ' + var[2] + '= 1', var[1]), self)
465+
else:
466+
for var in self.postIncDecVars:
467+
left, op = var
468+
self.addSource(('%s ' + op + "= 1", left))
469+
self.postIncDecVars = []
470+
self.postIncDecInExprFixed = False
471+
return expr
472+
473+
def hasAssignInExpr(self, expr):
474+
from lexer import ASSIGN, INC, DEC, POST_INC, POST_DEC, BAND_ASSIGN, SL_ASSIGN, BSR_ASSIGN, SR_ASSIGN, MOD_ASSIGN, DIV_ASSIGN, STAR_ASSIGN, MINUS_ASSIGN, PLUS_ASSIGN
475+
if expr.getType() in (ASSIGN, INC, DEC, POST_INC, POST_DEC, BAND_ASSIGN, SL_ASSIGN, BSR_ASSIGN, SR_ASSIGN, MOD_ASSIGN, DIV_ASSIGN, STAR_ASSIGN, MINUS_ASSIGN, PLUS_ASSIGN):
476+
return True
477+
child = expr.getFirstChild()
478+
while child:
479+
ret = self.hasAssignInExpr(child)
480+
if ret: return True
481+
child = child.getNextSibling()
482+
return False
409483

410484
class Module(Source):
411485
""" Module -> specialized block type

java2python/lib/walker.g

Lines changed: 100 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -391,25 +391,40 @@ statement [block]
391391

392392

393393
| {
394-
while_stat = block.newStatement("while")
394+
if_stat = while_stat = block.newStatement("while")
395395
}
396-
#("while" while_expr = expression[block, False]
397-
statement[while_stat])
396+
#(wh:"while"
397+
{
398+
useif = block.hasAssignInExpr(wh.getFirstChild())
399+
if (useif):
400+
if_stat = while_stat.newStatement("if")
401+
while_stat.setExpression("True")
402+
if_stat.newStatement("break")
403+
}
404+
while_expr = expression[if_stat, False]
405+
statement[while_stat])
398406
{
399-
while_stat.setExpression(while_expr)
407+
if useif:
408+
if_stat.setExpression(("not %s", while_expr))
409+
else:
410+
if_stat.setExpression(while_expr)
400411
}
401412

402413

403414
| {
404415
while_stat = block.newStatement("while")
405416
while_stat.setExpression("True")
406417
}
407-
#("do" statement[while_stat] do_exp = expression[block, False])
408-
{
418+
#("do"
419+
statement[while_stat]
420+
{
409421
if_stat = while_stat.newStatement("if")
410-
if_stat.setExpression(("not %s", do_exp))
411422
if_stat.newStatement("break")
412-
}
423+
}
424+
do_exp = expression[if_stat, False])
425+
{
426+
if_stat.setExpression(("not %s", do_exp))
427+
}
413428

414429

415430
| {
@@ -550,61 +565,117 @@ returns [seq]
550565

551566
expression [block, append=True]
552567
returns [exp]
553-
: #(EXPR exp = expr[block])
568+
: {
569+
fixAssign = not append
570+
}
571+
#(EXPR exp = expr[block, fixAssign])
554572
{
555573
if append:
556574
block.addSource(exp)
575+
if block.postIncDecInExprFixed:
576+
exp = block.fixPostIncDecInExprAfter(exp)
557577
}
558578
;
559579

560580

561-
expr [block]
581+
expr [block, fixAssign=True]
562582
returns [exp = block.unknownExpression]
563583
: #(QUESTION a0=expr[block] b0=expr[block] c0=expr[block])
564584
{exp = ("%s %s", (("%s", b0), ("%s %s", (("if %s", a0), ("else %s", c0)))))}
565585

566586
| #(ASSIGN left=expr[block] right=expr[block])
567-
{exp = ("%s = %s", (left, right))}
587+
{exp = block.fixAssignInExpr(fixAssign, ("%s = %s", (left, right)), left)}
568588

569589
| #(PLUS_ASSIGN left=expr[block] right=expr[block])
570-
{exp = ("%s += %s", (left, right))}
590+
{exp = block.fixAssignInExpr(fixAssign, ("%s += %s", (left, right)), left)}
571591

572592
| #(MINUS_ASSIGN left=expr[block] right=expr[block])
573-
{exp = ("%s -= %s", (left, right))}
593+
{exp = block.fixAssignInExpr(fixAssign, ("%s -= %s", (left, right)), left)}
574594

575595
| #(STAR_ASSIGN left=expr[block] right=expr[block])
576-
{exp = ("%s *= %s", (left, right))}
596+
{exp = block.fixAssignInExpr(fixAssign, ("%s *= %s", (left, right)), left)}
577597

578598
| #(DIV_ASSIGN left=expr[block] right=expr[block])
579-
{exp = ("%s /= %s", (left, right))}
599+
{exp = block.fixAssignInExpr(fixAssign, ("%s /= %s", (left, right)), left)}
580600

581601
| #(MOD_ASSIGN left=expr[block] right=expr[block])
582-
{exp = ("%s %%= %s", (left, right))}
602+
{exp = block.fixAssignInExpr(fixAssign, ("%s %%= %s", (left, right)), left)}
583603

584604
| #(SR_ASSIGN left=expr[block] right=expr[block])
585-
{exp = ("%s >>= %s", (left, right))}
605+
{exp = block.fixAssignInExpr(fixAssign, ("%s >>= %s", (left, right)), left)}
586606

587607
| #(BSR_ASSIGN left=expr[block] right=expr[block])
588608
// raise an exception during parsing, not at runtime
589609
{raise NotImplementedError("BSR_ASSIGN")}
590610

591611
| #(SL_ASSIGN left=expr[block] right=expr[block])
592-
{exp = ("%s <<= %s", (left, right))}
612+
{exp = block.fixAssignInExpr(fixAssign, ("%s <<= %s", (left, right)), left)}
593613

594614
| #(BAND_ASSIGN left=expr[block] right=expr[block])
595-
{exp = ("%s &= %s", (left, right))}
615+
{exp = block.fixAssignInExpr(fixAssign, ("%s &= %s", (left, right)), left)}
596616

597617
| #(BXOR_ASSIGN left=expr[block] right=expr[block])
598-
{exp = ("%s ^= %s", (left, right))}
618+
{exp = block.fixAssignInExpr(fixAssign, ("%s ^= %s", (left, right)), left)}
599619

600620
| #(BOR_ASSIGN left=expr[block] right=expr[block])
601-
{exp = ("%s |= %s", (left, right))}
621+
{exp = block.fixAssignInExpr(fixAssign, ("%s |= %s", (left, right)), left)}
622+
623+
| { left_if = right_if = block }
624+
#(lor:LOR
625+
{
626+
right_has = block.hasAssignInExpr(lor.getFirstChild().getNextSibling())
627+
if right_has:
628+
left_if = block.parent.newStatementBefore("if", block)
629+
right_if = left_if.newStatement("if")
630+
}
631+
left=expr[left_if] right=expr[right_if])
632+
{
633+
if right_has:
634+
left_if.setExpression(("not %s", left))
635+
if left != "_ret":
636+
left_else = block.parent.newStatementBefore("else", block)
637+
left_else.addSource("_ret = True")
638+
right_if.setExpression(right)
639+
right_if.addSource("_ret = True")
640+
right_else = left_if.newStatement("else")
641+
right_else.addSource("_ret = False")
642+
if left_if.postIncDecInExprFixed:
643+
left_if.fixPostIncDecInExprAfter(left)
644+
if right_if.postIncDecInExprFixed:
645+
right_if.fixPostIncDecInExprAfter(right)
646+
exp = "_ret"
647+
else:
648+
exp = ("%s or %s", (left, right))
602649

603-
| #(LOR left=expr[block] right=expr[block])
604-
{exp = ("%s or %s", (left, right))}
650+
}
605651

606-
| #(LAND left=expr[block] right=expr[block])
607-
{exp = ("%s and %s", (left, right))}
652+
| { left_if = right_if = block }
653+
#(land:LAND
654+
{
655+
right_has = block.hasAssignInExpr(land.getFirstChild().getNextSibling())
656+
if right_has:
657+
left_if = block.parent.newStatementBefore("if", block)
658+
right_if = left_if.newStatement("if")
659+
}
660+
left=expr[left_if] right=expr[right_if])
661+
{
662+
if right_has:
663+
left_if.setExpression(left)
664+
if left != "_ret":
665+
left_else = block.parent.newStatementBefore("else", block)
666+
left_else.addSource("_ret = False")
667+
right_if.setExpression(right)
668+
right_if.addSource("_ret = True")
669+
right_else = left_if.newStatement("else")
670+
right_else.addSource("_ret = False")
671+
if left_if.postIncDecInExprFixed:
672+
left_if.fixPostIncDecInExprAfter(left)
673+
if right_if.postIncDecInExprFixed:
674+
right_if.fixPostIncDecInExprAfter(right)
675+
exp = "_ret"
676+
else:
677+
exp = ("%s and %s", (left, right))
678+
}
608679

609680
| #(BOR left=expr[block] right=expr[block])
610681
{exp = ("%s | %s", (left, right))}
@@ -669,16 +740,16 @@ returns [exp = block.unknownExpression]
669740
{exp = ("%s * %s", (left, right))}
670741

671742
| #(INC ex=expr[block])
672-
{exp = ("%s += 1", ex)}
743+
{exp = block.fixAssignInExpr(fixAssign, ("%s += 1", ex), ex)}
673744

674745
| #(DEC ex=expr[block])
675-
{exp = ("%s -= 1", ex)}
746+
{exp = block.fixAssignInExpr(fixAssign, ("%s -= 1", ex), ex)}
676747

677748
| #(POST_INC ex=expr[block])
678-
{exp = ("%s += 1", ex)}
749+
{exp = block.fixPostIncDecInExpr(fixAssign, ("%s += 1", ex), ex, "+")}
679750

680751
| #(POST_DEC ex=expr[block])
681-
{exp = ("%s -= 1", ex)}
752+
{exp = block.fixPostIncDecInExpr(fixAssign, ("%s -= 1", ex), ex, "-")}
682753

683754
| #(BNOT ex=expr[block])
684755
{exp = ("~%s", ex)}

0 commit comments

Comments
 (0)