Package VisionEgg :: Package PyroApps :: Module AST_ext |
[frames] | no frames]

# Source Code for Module VisionEgg.PyroApps.AST_ext

      1  ## Automatically adapted for numpy.oldnumeric Jun 18, 2007 by alter_code1.py
      2
      3  # The Vision Egg: AST_ext
      4  #
      5  # Copyright (C) 2004 Imran S. Ali, Lachlan Dowd
      6  #
      7  # Authors: Imran S. Ali, Lachlan Dowd
      8  # URL: <http://www.visionegg.org/>
      9  #
     10  # Distributed under the terms of the GNU Lesser General Public License
     11  # (LGPL). See LICENSE.TXT that came with this file.
     12  #
     13  # $Id$
     14
     15  # This "AST extensions" module works for Python 2.2.1
     16  # Because the structure of code trees changes with different Python versions, this module may not work with some
     17  # previous Python releases, or future releases.
     18
     19  import pprint
     20  import parser
     21  import symbol
     22  import token
     23  import tokenize
     24  import sys
     25
     26  # Hopefully, the node ID numbers in the name sequence is all that
     27  # needs to be changed in order to get this module working with
     28  # different Python release versions.
     29
     30  name_sequence = [292, 293, 294, 295, 297, 298, 299, 300, 301, 302,
     31  303, 304, 305]
     32
     33  # Method for generating an AST sub tree (in list form) suitable for a
     34 -def gen_assign_val_subtree(assign_val, assign_val_type):
     35      name_sequence.reverse()
     36      sublist = []
     37      if assign_val_type == 2:
     38          sublist = [2, '%(assign_val)d' % vars()]
     39      elif assign_val_type == 1:
     40          sublist = [2, '%(assign_val)f' % vars()]
     41      elif assign_val_type == 3:
     42          sublist = [3, '"%(assign_val)s"' % vars()]
     43      for val in name_sequence[0:len(name_sequence) - 1]:
     44          sublist = [val, sublist]
     45      name_sequence.reverse()
     46      return sublist
     47
     48
     49 -class AST_Visitor:
     50 -    def __init__(self, modifying_AST):
     51          # Flags:
     52
     53          # Checking assignment name (ie. "x = ..." where we are
     54          # checking if 'x' == 'assign_name'):
     55          self.checking_assign_name = 0
     56
     57          # Setting assignment value (we are changing a found occurrence
     58          # of "assign_name = x" to "assign_name = assign_val"):
     59          self.setting_assign_val = 0
     60
     61          # Index of where the AST visitor is currently at in the
     62          # 'name_sequence' defined earlier:
     63          self.name_seq_index = 0
     64
     65          # AST visitor expects a subtree associated with
     66          # assignment/"=":
     67          self.expecting_equals = 0
     68
     69          # Extracting assignment value (we are extracting the 'x' from
     70          # a found occurrence of "assign_name = x"):
     71          self.extracting_assign_val = 0
     72
     73          # Extracted assignment value:
     74          self.extracted_val = "not found"
     75
     76          # Are we modifying an AST? Otherwise we're extracting
     77          # information from an AST:
     78          self.modifying_AST = modifying_AST
     79
     80 -    def traverse(self, AST_sublist, assign_name, assign_val_subtree):
     81
     82          # If we have a single element (terminating leaf node):
     83          if type(AST_sublist) != list:
     84              return AST_sublist
     85
     86          # If we have a sub tree of the form [x, [....]]:
     87          elif len(AST_sublist) == 2:
     88
     89              # If we are somewhere in the 'name_sequence' defined
     90              # earlier: [292, [293, [294, [295, [297, [298, [299, [300,
     91              # [301, [302, [303, [304, [305, ...
     92
     93              if self.name_seq_index > 0:
     94                  # If we are at the end of the 'name_sequence':
     95                  if self.name_seq_index == len(name_sequence) - 1 and AST_sublist[0] == name_sequence[self.name_seq_index]:
     96                      if len(AST_sublist[1]) == 3:
     97                          if self.extracting_assign_val == 1:
     98                              extracted_val = AST_sublist[1][1]
     99                              self.extracted_val = extracted_val
    100                              self.extracting_assign_val = 0
    101                          else:
    102                              # Enter new mode: AST visitor will check
    103                              # the name associated with the
    104                              # 'name_sequence' to see if it will match
    105                              # 'assign_name':
    106                              self.checking_assign_name = 1
    107                      self.name_seq_index = 0
    108
    109                  else:
    110                      expected_val = name_sequence[self.name_seq_index]
    111                      if AST_sublist[0] == expected_val:
    112                          # Update position in 'name_sequence':
    113                          self.name_seq_index = self.name_seq_index + 1
    114                      else:
    115                          self.name_seq_index = 0
    116                  return AST_sublist[0:1] + [self.traverse(AST_sublist[1], assign_name, assign_val_subtree)]
    117
    118              # Else we are in some arbitrary sequence:
    119              # [a, [b, [c, [d, [e, [...
    120              else:
    121                  # If we are at the start of the 'name_sequence':
    122                  if AST_sublist[0] == 292:
    123                      if self.setting_assign_val == 1:
    124                          AST_sublist[1] = assign_val_subtree
    125                          self.setting_assign_val = 0
    126                      else:
    127                          # Enter new mode: AST visitor will check to
    128                          # see if we are progressing through the
    129                          # 'name_sequence' defined earlier:
    130                          self.name_seq_index = 1
    131                      return AST_sublist[0:1] + [self.traverse(AST_sublist[1], assign_name, assign_val_subtree)]
    132                  else:
    133                      return AST_sublist[0:1] + [self.traverse(AST_sublist[1], assign_name, assign_val_subtree)]
    134
    135          # If we have a sub tree with 3 parent nodes:
    136          elif len(AST_sublist) == 3:
    137
    138              # If the second parent node is a single element
    139              # (terminating leaf node):
    140              if type(AST_sublist[1]) != list:
    141                  # If the current AST visitor mode is set to checking
    142                  # for equality with "assign_name" (ie. "x = ..." where
    143                  # we are checking if 'x' == 'assign_name')::
    144                  if self.checking_assign_name == 1:
    145                      # If 'x' == 'assign_name' (see above):
    146                      if AST_sublist[1] == assign_name:
    147                          # Enter new mode: AST visitor will check to
    148                          # see if the current sub tree is associated
    149                          # with assignment/"=":
    150                          self.expecting_equals = 1
    151                      self.checking_assign_name = 0
    152
    153                  # If the current AST visitor mode is set to check if
    154                  # the current sub tree is associated with
    155                  # assignment/"=":
    156                  elif self.expecting_equals == 1:
    157                      # If the current AST sub tree is associated with
    158                      # assignment/"=":
    159                      if AST_sublist[1] == '=':
    160                          if self.modifying_AST == 1:
    161                              # Enter new mode: AST visitor will change
    162                              # the assignment value to
    163                              # "assign_val_subtree":
    164                              self.setting_assign_val = 1
    165                          elif self.modifying_AST == 0:
    166                              # Enter new mode: AST visitor will extract
    167                              # the assignment value of "assign_name":
    168                              self.extracting_assign_val = 1
    169                      self.expecting_equals = 0
    170
    171                  return AST_sublist[0:2]
    172
    173          # If we are somewhere within the 'name_sequence':
    174          if self.name_seq_index > 0 or self.name_seq_index < len(name_sequence) - 1:
    175              # If the AST visitor is extracting the value of "assign_name":
    176              if self.extracting_assign_val == 1:
    177                  self.extracted_val = "compound"
    178                  self.extracting_assign_val = 0
    179
    180
    181          # For all other types of sub trees, AST visitor will traverse
    182          # in a depth first search pattern:
    183          sub_list = []
    184          for x in AST_sublist:
    185              sub_list = sub_list + [self.traverse(x, assign_name, assign_val_subtree)]
    186          return sub_list
    187
    188 -def modify_AST(myAST, assign_name, assign_val):
    189      myAST_Visitor = AST_Visitor(1)
    190      old_AST_list = myAST.tolist(1)
    191      assign_val_type = 0
    192      if isinstance(assign_val, int):
    193          assign_val_type = 2
    194      elif isinstance(assign_val, float):
    195          assign_val_type = 1
    196      elif type(assign_val) == str:
    197          assign_val_type = 3
    198      new_AST_list = myAST_Visitor.traverse(old_AST_list, assign_name, gen_assign_val_subtree(assign_val, assign_val_type))
    199      myNewAST = parser.sequence2ast(new_AST_list)
    200      return myNewAST
    201
    202  # Extract the assigned value of a variable from an AST. Retains the type.
    203 -def extract_from_AST(myAST, assign_name):
    204      myAST_Visitor = AST_Visitor(0)
    205      old_AST_list = myAST.tolist(1)
    206      new_AST_list = myAST_Visitor.traverse(old_AST_list, assign_name, 0)
    207      return myAST_Visitor.extracted_val
    208