예제 #1
0
 def AUGASSIGN(self, node):
     # AugAssign is awkward: must set the context explicitly and visit twice,
     # once with AugLoad context, once with AugStore context
     node.target.ctx = _ast.AugLoad()
     self.handleNode(node.target, node)
     self.handleNode(node.value, node)
     node.target.ctx = _ast.AugStore()
     self.handleNode(node.target, node)
예제 #2
0
  def make_assign(i, bytecode):
    op = bytecode[i][2]
    if op == STORE_SUBSCR:
      return Statement.make_subscript(i, bytecode)

    prev_op = bytecode[i - 1][2] if i > 0 else -1

    if prev_op in INPLACE_OPCODES:
      in_cls = Statement.INPLACE_OPERATORS[prev_op]
      i -= 1
      i, rhs = Statement.make_expr(i - 1, bytecode, context=_ast.AugStore())
      i, lhs = Statement.make_expr(i - 1, bytecode, context=_ast.AugLoad())
      return i, _ast.AugAssign(lhs, in_cls(), rhs)
    else:
      # We can either have multiple assignments: a = b = c = 1
      # or unpacked sequences: a, b = 1, foo()
      # the compiler does some optimization so that: a, b = c, d
      # does not rely on UNPACK_SEQUENCE, but a ROT_TWO (or ROT_THREE & ROT_TWO for 3 elements).
      # This happens for 2 or 3 elements to unpack
      targets = []
      value = None
      has_unpack, has_ROT_2_3, has_multiple = False, False, 0
      num_unpack = -1
      j = i
      while j >= 0:
        op = bytecode[j][2]
        if op == UNPACK_SEQUENCE:
          has_unpack = True
          num_unpack = bytecode[j][3]
          break
        elif op in (ROT_TWO, ROT_THREE):
          has_ROT_2_3 = True
          break
        if op == DUP_TOP:
          has_multiple += 1
        j -= 1

      if has_unpack:
        return Statement.make_assign_unpack(i, bytecode, unpack_num=num_unpack)
      elif has_ROT_2_3:
        return Statement.make_assign_opt_unpack(i, bytecode)
      elif has_multiple > 0:
        return Statement.make_assign_chained(i, bytecode)
      else:
        # A simple assignment
        i, store_expr = Statement.make_expr(i, bytecode)
        i, value_expr = Statement.make_expr(i - 1, bytecode)
        return i, _ast.Assign([store_expr], value_expr)
    return i, None